Skip to content

Commit f9a7703

Browse files
committed
docs: provide static and dynamic examples
1 parent 7eac963 commit f9a7703

File tree

7 files changed

+328
-122
lines changed

7 files changed

+328
-122
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

+2-29
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,11 @@ title: Using BottomNavigation with React Navigation
33
---
44

55
:::caution
6-
`createMaterialBottomTabNavigator` has been deprecated since `[email protected]`. Please use `@react-navigation/bottom-tabs` version `7.x` or higher and combine it with `BottomNavigation.Bar` for a Material Design look.
7-
8-
```js
9-
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
10-
import { BottomNavigation } from 'react-native-paper';
11-
12-
const Tab = createBottomTabNavigator();
13-
14-
function MyTabs() {
15-
return (
16-
<Tab.Navigator
17-
tabBar={({ navigation, state, descriptors, insets }) => (
18-
<BottomNavigation.Bar
19-
...
20-
/>
21-
)}
22-
>
23-
<Tab.Screen name="Home" component={HomeScreen} />
24-
<Tab.Screen name="Profile" component={ProfileScreen} />
25-
</Tab.Navigator>
26-
);
27-
}
28-
```
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.
297

8+
For implementation details, see the [dedicated example](https://callstack.github.io/react-native-paper/docs/components/BottomNavigation/BottomNavigationBar#with-react-navigation).
309
:::
3110

32-
> 👉 For a complete example please visit `createBottomTabNavigator` [snack](https://snack.expo.dev/@react-native-paper/createbottomtabnavigator-with-bottomnavigationbar).
33-
34-
---
35-
36-
_For projects using `react-native-paper` < `5.14.0` and `react-navigation` < `7.x`, proceed as follows:_
37-
3811
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.
3912

4013
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.

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+
Profile: {
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+
};

0 commit comments

Comments
 (0)