Skip to content

Commit 53ca1f6

Browse files
authored
chore: deprecate createMaterialBottomTabNavigator (#4694)
1 parent 699bb06 commit 53ca1f6

19 files changed

+597
-371
lines changed

docs/component-docs-plugin/generatePageMDX.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,22 @@ function generateExtendsAttributes(doc) {
166166
return extendsAttributes;
167167
}
168168

169+
function generateExtendedExamples(usage, extendedExamplesData) {
170+
if (!extendedExamplesData) {
171+
return usage;
172+
}
173+
174+
const data = JSON.parse(extendedExamplesData);
175+
const exampleHeader = Object.keys(data)[0];
176+
177+
return `
178+
${usage}
179+
180+
### ${exampleHeader}
181+
<ExtendedExample extendedExamplesData={${extendedExamplesData}} />
182+
`;
183+
}
184+
169185
function generatePageMDX(doc, link) {
170186
const summaryRegex = /([\s\S]*?)## Usage/;
171187

@@ -182,6 +198,9 @@ function generatePageMDX(doc, link) {
182198

183199
const themeColorsData = JSON.stringify(customFields.themeColors[doc.title]);
184200
const screenshotData = JSON.stringify(customFields.screenshots[doc.title]);
201+
const extendedExamplesData = JSON.stringify(
202+
customFields.extendedExamples[doc.title]
203+
);
185204

186205
const extendsAttributes = generateExtendsAttributes(doc);
187206

@@ -194,12 +213,13 @@ import PropTable from '@site/src/components/PropTable.tsx';
194213
import ExtendsLink from '@site/src/components/ExtendsLink.tsx';
195214
import ThemeColorsTable from '@site/src/components/ThemeColorsTable.tsx';
196215
import ScreenshotTabs from '@site/src/components/ScreenshotTabs.tsx';
216+
import ExtendedExample from '@site/src/components/ExtendedExample.tsx';
197217
198218
${summary}
199219
200220
${generateScreenshots(doc.title, screenshotData)}
201221
202-
${usage}
222+
${generateExtendedExamples(usage, extendedExamplesData)}
203223
204224
${generatePropsTable(doc.data.props, link, extendsAttributes)}
205225

docs/docs/guides/09-bottom-navigation.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
title: Using BottomNavigation with React Navigation
33
---
44

5+
:::caution
6+
The `createMaterialBottomTabNavigator` has been deprecated as of `[email protected]`. Instead, use `@react-navigation/bottom-tabs` version `7.x` or later, combined with `BottomNavigation.Bar` to achieve a Material Design look.
7+
8+
For implementation details, see the [dedicated example](https://callstack.github.io/react-native-paper/docs/components/BottomNavigation/BottomNavigationBar#with-react-navigation).
9+
:::
10+
511
A material-design themed tab bar on the bottom of the screen that lets you switch between different routes with animation. Routes are lazily initialized - their screen components are not mounted until they are first focused.
612

713
This wraps the [`BottomNavigation`](https://callstack.github.io/react-native-paper/docs/components/BottomNavigation/) component from `react-native-paper`, however if you [configure the Babel plugin](https://callstack.github.io/react-native-paper/docs/guides/getting-started/), it won't include the whole library in your bundle.
@@ -12,7 +18,7 @@ This wraps the [`BottomNavigation`](https://callstack.github.io/react-native-pap
1218
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](https://reactnavigation.org/docs/getting-started):
1319
:::
1420

15-
> For a complete example please visit `createMaterialBottomTabNavigator` [snack](https://snack.expo.dev/@react-native-paper/creatematerialbottomtabnavigator)
21+
> 👉 For a complete example please visit `createMaterialBottomTabNavigator` [snack](https://snack.expo.dev/@react-native-paper/creatematerialbottomtabnavigator)
1622
1723
## API Definition
1824

@@ -33,7 +39,7 @@ function MyTabs() {
3339
}
3440
```
3541

36-
> For a complete usage guide please visit [Tab Navigation](https://reactnavigation.org/docs/tab-based-navigation/)
42+
> 👉 For a complete usage guide please visit [Tab Navigation](https://reactnavigation.org/docs/tab-based-navigation/)
3743
3844
### Props
3945

docs/docusaurus.config.js

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const path = require('path');
55
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
66
const lightCodeTheme = require('prism-react-renderer/themes/github');
77

8+
const { extendedExamples } = require('./src/data/extendedExamples.js');
89
const { screenshots } = require('./src/data/screenshots.js');
910
const { themeColors } = require('./src/data/themeColors.js');
1011

@@ -336,6 +337,7 @@ const config = {
336337
},
337338
themeColors,
338339
screenshots,
340+
extendedExamples,
339341
},
340342
};
341343

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react';
2+
3+
//@ts-ignore
4+
import CodeBlock from '@theme/CodeBlock';
5+
//@ts-ignore
6+
import TabItem from '@theme/TabItem';
7+
//@ts-ignore
8+
import Tabs from '@theme/Tabs';
9+
10+
interface ExtendedExampleProps {
11+
extendedExamplesData: {
12+
[key: string]: {
13+
[key: string]: string;
14+
};
15+
};
16+
}
17+
18+
const ExtendedExample = ({ extendedExamplesData }: ExtendedExampleProps) => {
19+
const example = Object.values(extendedExamplesData)[0];
20+
21+
if (!example) return null;
22+
23+
const keys = Object.keys(example);
24+
25+
return (
26+
<Tabs>
27+
{keys.map((key) => (
28+
<TabItem value={key} label={key} key={key}>
29+
<CodeBlock language="jsx">{example[key]}</CodeBlock>
30+
</TabItem>
31+
))}
32+
</Tabs>
33+
);
34+
};
35+
36+
export default ExtendedExample;

docs/src/data/extendedExamples.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const {
2+
staticCode,
3+
dynamicCode,
4+
} = require('./extendedExamples/BottomNavigationBar');
5+
6+
const extendedExamples = {
7+
'BottomNavigation.Bar': {
8+
'with React Navigation': {
9+
static: staticCode,
10+
dynamic: dynamicCode,
11+
},
12+
},
13+
};
14+
15+
module.exports = {
16+
extendedExamples,
17+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
const staticCode = `import { Text, View } from 'react-native';
2+
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
3+
import { Provider, BottomNavigation } from 'react-native-paper';
4+
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
5+
import {
6+
CommonActions,
7+
createStaticNavigation,
8+
} from '@react-navigation/native';
9+
10+
function HomeScreen() {
11+
return (
12+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
13+
<Text>Home!</Text>
14+
</View>
15+
);
16+
}
17+
18+
function SettingsScreen() {
19+
return (
20+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
21+
<Text>Settings!</Text>
22+
</View>
23+
);
24+
}
25+
26+
const MyTabs = createBottomTabNavigator({
27+
screenOptions: {
28+
animation: 'shift',
29+
},
30+
tabBar: ({ navigation, state, descriptors, insets }) => (
31+
<BottomNavigation.Bar
32+
navigationState={state}
33+
safeAreaInsets={insets}
34+
onTabPress={({ route, preventDefault }) => {
35+
const event = navigation.emit({
36+
type: 'tabPress',
37+
target: route.key,
38+
canPreventDefault: true,
39+
});
40+
41+
if (event.defaultPrevented) {
42+
preventDefault();
43+
} else {
44+
navigation.dispatch({
45+
...CommonActions.navigate(route.name, route.params),
46+
target: state.key,
47+
});
48+
}
49+
}}
50+
renderIcon={({ route, focused, color }) =>
51+
descriptors[route.key].options.tabBarIcon?.({
52+
focused,
53+
color,
54+
size: 24,
55+
}) || null
56+
}
57+
getLabelText={({ route }) => {
58+
const { options } = descriptors[route.key];
59+
const label =
60+
typeof options.tabBarLabel === 'string'
61+
? options.tabBarLabel
62+
: typeof options.title === 'string'
63+
? options.title
64+
: route.name;
65+
66+
return label;
67+
}}
68+
/>
69+
),
70+
screens: {
71+
Home: {
72+
screen: HomeScreen,
73+
options: {
74+
tabBarIcon: ({ color }) => (
75+
<MaterialCommunityIcons name="home" color={color} size={26} />
76+
),
77+
},
78+
},
79+
Settings: {
80+
screen: SettingsScreen,
81+
options: {
82+
tabBarIcon: ({ color }) => (
83+
<MaterialCommunityIcons name="cog" color={color} size={26} />
84+
),
85+
},
86+
},
87+
},
88+
});
89+
90+
const Navigation = createStaticNavigation(MyTabs);
91+
92+
export default function App() {
93+
return (
94+
<Provider>
95+
<Navigation>
96+
<MyTabs />
97+
</Navigation>
98+
</Provider>
99+
);
100+
}`;
101+
102+
const dynamicCode = `import { Text, View } from 'react-native';
103+
import { NavigationContainer, CommonActions } from '@react-navigation/native';
104+
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
105+
import { Provider, BottomNavigation } from 'react-native-paper';
106+
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
107+
108+
function HomeScreen() {
109+
return (
110+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
111+
<Text>Home!</Text>
112+
</View>
113+
);
114+
}
115+
116+
function SettingsScreen() {
117+
return (
118+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
119+
<Text>Settings!</Text>
120+
</View>
121+
);
122+
}
123+
124+
const Tab = createBottomTabNavigator();
125+
126+
export default function App() {
127+
return (
128+
<Provider>
129+
<NavigationContainer>
130+
<Tab.Navigator
131+
screenOptions={{
132+
animation: 'shift',
133+
}}
134+
tabBar={({ navigation, state, descriptors, insets }) => (
135+
<BottomNavigation.Bar
136+
navigationState={state}
137+
safeAreaInsets={insets}
138+
onTabPress={({ route, preventDefault }) => {
139+
const event = navigation.emit({
140+
type: 'tabPress',
141+
target: route.key,
142+
canPreventDefault: true,
143+
});
144+
145+
if (event.defaultPrevented) {
146+
preventDefault();
147+
} else {
148+
navigation.dispatch({
149+
...CommonActions.navigate(route.name, route.params),
150+
target: state.key,
151+
});
152+
}
153+
}}
154+
renderIcon={({ route, focused, color }) =>
155+
descriptors[route.key].options.tabBarIcon?.({
156+
focused,
157+
color,
158+
size: 24,
159+
}) || null
160+
}
161+
getLabelText={({ route }) => {
162+
const { options } = descriptors[route.key];
163+
const label =
164+
typeof options.tabBarLabel === 'string'
165+
? options.tabBarLabel
166+
: typeof options.title === 'string'
167+
? options.title
168+
: route.name;
169+
170+
return label;
171+
}}
172+
/>
173+
)}>
174+
<Tab.Screen
175+
name="Home"
176+
component={HomeScreen}
177+
options={{
178+
tabBarIcon: ({ color }) => (
179+
<MaterialCommunityIcons name="home" color={color} size={26} />
180+
),
181+
}}
182+
/>
183+
<Tab.Screen
184+
name="Settings"
185+
component={SettingsScreen}
186+
options={{
187+
tabBarIcon: ({ color }) => (
188+
<MaterialCommunityIcons name="cog" color={color} size={26} />
189+
),
190+
}}
191+
/>
192+
</Tab.Navigator>
193+
</NavigationContainer>
194+
</Provider>
195+
);
196+
}
197+
`;
198+
199+
module.exports = {
200+
staticCode,
201+
dynamicCode,
202+
};

example/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
"@pchmn/expo-material3-theme": "^1.3.2",
2020
"@react-native-async-storage/async-storage": "1.23.1",
2121
"@react-native-masked-view/masked-view": "0.3.2",
22-
"@react-navigation/bottom-tabs": "^6.6.1",
23-
"@react-navigation/drawer": "^6.7.2",
24-
"@react-navigation/native": "^6.1.18",
25-
"@react-navigation/stack": "^6.4.1",
22+
"@react-navigation/bottom-tabs": "^7.3.10",
23+
"@react-navigation/drawer": "^7.3.9",
24+
"@react-navigation/native": "^7.1.6",
25+
"@react-navigation/stack": "^7.2.10",
2626
"expo": "^52.0.0",
2727
"expo-crypto": "~14.0.1",
2828
"expo-dev-client": "~5.0.4",

example/src/ExampleList.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import ListAccordionExample from './Examples/ListAccordionExample';
2828
import ListAccordionExampleGroup from './Examples/ListAccordionGroupExample';
2929
import ListItemExample from './Examples/ListItemExample';
3030
import ListSectionExample from './Examples/ListSectionExample';
31-
import MaterialBottomTabNavigatorExample from './Examples/MaterialBottomTabNavigatorExample';
3231
import MenuExample from './Examples/MenuExample';
3332
import ProgressBarExample from './Examples/ProgressBarExample';
3433
import RadioButtonExample from './Examples/RadioButtonExample';
@@ -80,7 +79,6 @@ export const mainExamples: Record<
8079
listAccordionGroup: ListAccordionExampleGroup,
8180
listSection: ListSectionExample,
8281
listItem: ListItemExample,
83-
materialBottomTabNavigator: MaterialBottomTabNavigatorExample,
8482
menu: MenuExample,
8583
progressbar: ProgressBarExample,
8684
radio: RadioButtonExample,

0 commit comments

Comments
 (0)