diff --git a/docs/component-docs-plugin/generatePageMDX.js b/docs/component-docs-plugin/generatePageMDX.js index 2a6c05a084..0165ecdb8d 100644 --- a/docs/component-docs-plugin/generatePageMDX.js +++ b/docs/component-docs-plugin/generatePageMDX.js @@ -166,6 +166,22 @@ function generateExtendsAttributes(doc) { return extendsAttributes; } +function generateExtendedExamples(usage, extendedExamplesData) { + if (!extendedExamplesData) { + return usage; + } + + const data = JSON.parse(extendedExamplesData); + const exampleHeader = Object.keys(data)[0]; + + return ` + ${usage} + + ### ${exampleHeader} + + `; +} + function generatePageMDX(doc, link) { const summaryRegex = /([\s\S]*?)## Usage/; @@ -182,6 +198,9 @@ function generatePageMDX(doc, link) { const themeColorsData = JSON.stringify(customFields.themeColors[doc.title]); const screenshotData = JSON.stringify(customFields.screenshots[doc.title]); + const extendedExamplesData = JSON.stringify( + customFields.extendedExamples[doc.title] + ); const extendsAttributes = generateExtendsAttributes(doc); @@ -194,12 +213,13 @@ import PropTable from '@site/src/components/PropTable.tsx'; import ExtendsLink from '@site/src/components/ExtendsLink.tsx'; import ThemeColorsTable from '@site/src/components/ThemeColorsTable.tsx'; import ScreenshotTabs from '@site/src/components/ScreenshotTabs.tsx'; +import ExtendedExample from '@site/src/components/ExtendedExample.tsx'; ${summary} ${generateScreenshots(doc.title, screenshotData)} -${usage} +${generateExtendedExamples(usage, extendedExamplesData)} ${generatePropsTable(doc.data.props, link, extendsAttributes)} diff --git a/docs/docs/guides/09-bottom-navigation.md b/docs/docs/guides/09-bottom-navigation.md index ba3bc33f3a..21776718c9 100644 --- a/docs/docs/guides/09-bottom-navigation.md +++ b/docs/docs/guides/09-bottom-navigation.md @@ -2,6 +2,12 @@ title: Using BottomNavigation with React Navigation --- +:::caution +The `createMaterialBottomTabNavigator` has been deprecated as of `react-native-paper@5.14.0`. Instead, use `@react-navigation/bottom-tabs` version `7.x` or later, combined with `BottomNavigation.Bar` to achieve a Material Design look. + +For implementation details, see the [dedicated example](https://callstack.github.io/react-native-paper/docs/components/BottomNavigation/BottomNavigationBar#with-react-navigation). +::: + 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. 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 To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](https://reactnavigation.org/docs/getting-started): ::: -> For a complete example please visit `createMaterialBottomTabNavigator` [snack](https://snack.expo.dev/@react-native-paper/creatematerialbottomtabnavigator) +> 👉 For a complete example please visit `createMaterialBottomTabNavigator` [snack](https://snack.expo.dev/@react-native-paper/creatematerialbottomtabnavigator) ## API Definition @@ -33,7 +39,7 @@ function MyTabs() { } ``` -> For a complete usage guide please visit [Tab Navigation](https://reactnavigation.org/docs/tab-based-navigation/) +> 👉 For a complete usage guide please visit [Tab Navigation](https://reactnavigation.org/docs/tab-based-navigation/) ### Props diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 16cd59f009..886044db0e 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -5,6 +5,7 @@ const path = require('path'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); const lightCodeTheme = require('prism-react-renderer/themes/github'); +const { extendedExamples } = require('./src/data/extendedExamples.js'); const { screenshots } = require('./src/data/screenshots.js'); const { themeColors } = require('./src/data/themeColors.js'); @@ -336,6 +337,7 @@ const config = { }, themeColors, screenshots, + extendedExamples, }, }; diff --git a/docs/src/components/ExtendedExample.tsx b/docs/src/components/ExtendedExample.tsx new file mode 100644 index 0000000000..c3eac15fdf --- /dev/null +++ b/docs/src/components/ExtendedExample.tsx @@ -0,0 +1,36 @@ +import React from 'react'; + +//@ts-ignore +import CodeBlock from '@theme/CodeBlock'; +//@ts-ignore +import TabItem from '@theme/TabItem'; +//@ts-ignore +import Tabs from '@theme/Tabs'; + +interface ExtendedExampleProps { + extendedExamplesData: { + [key: string]: { + [key: string]: string; + }; + }; +} + +const ExtendedExample = ({ extendedExamplesData }: ExtendedExampleProps) => { + const example = Object.values(extendedExamplesData)[0]; + + if (!example) return null; + + const keys = Object.keys(example); + + return ( + + {keys.map((key) => ( + + {example[key]} + + ))} + + ); +}; + +export default ExtendedExample; diff --git a/docs/src/data/extendedExamples.js b/docs/src/data/extendedExamples.js new file mode 100644 index 0000000000..f7b196afff --- /dev/null +++ b/docs/src/data/extendedExamples.js @@ -0,0 +1,17 @@ +const { + staticCode, + dynamicCode, +} = require('./extendedExamples/BottomNavigationBar'); + +const extendedExamples = { + 'BottomNavigation.Bar': { + 'with React Navigation': { + static: staticCode, + dynamic: dynamicCode, + }, + }, +}; + +module.exports = { + extendedExamples, +}; diff --git a/docs/src/data/extendedExamples/BottomNavigationBar.js b/docs/src/data/extendedExamples/BottomNavigationBar.js new file mode 100644 index 0000000000..81bb261a96 --- /dev/null +++ b/docs/src/data/extendedExamples/BottomNavigationBar.js @@ -0,0 +1,202 @@ +const staticCode = `import { Text, View } from 'react-native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { Provider, BottomNavigation } from 'react-native-paper'; +import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'; +import { + CommonActions, + createStaticNavigation, +} from '@react-navigation/native'; + +function HomeScreen() { + return ( + + Home! + + ); +} + +function SettingsScreen() { + return ( + + Settings! + + ); +} + +const MyTabs = createBottomTabNavigator({ + screenOptions: { + animation: 'shift', + }, + tabBar: ({ navigation, state, descriptors, insets }) => ( + { + const event = navigation.emit({ + type: 'tabPress', + target: route.key, + canPreventDefault: true, + }); + + if (event.defaultPrevented) { + preventDefault(); + } else { + navigation.dispatch({ + ...CommonActions.navigate(route.name, route.params), + target: state.key, + }); + } + }} + renderIcon={({ route, focused, color }) => + descriptors[route.key].options.tabBarIcon?.({ + focused, + color, + size: 24, + }) || null + } + getLabelText={({ route }) => { + const { options } = descriptors[route.key]; + const label = + typeof options.tabBarLabel === 'string' + ? options.tabBarLabel + : typeof options.title === 'string' + ? options.title + : route.name; + + return label; + }} + /> + ), + screens: { + Home: { + screen: HomeScreen, + options: { + tabBarIcon: ({ color }) => ( + + ), + }, + }, + Settings: { + screen: SettingsScreen, + options: { + tabBarIcon: ({ color }) => ( + + ), + }, + }, + }, +}); + +const Navigation = createStaticNavigation(MyTabs); + +export default function App() { + return ( + + + + + + ); +}`; + +const dynamicCode = `import { Text, View } from 'react-native'; +import { NavigationContainer, CommonActions } from '@react-navigation/native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { Provider, BottomNavigation } from 'react-native-paper'; +import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'; + +function HomeScreen() { + return ( + + Home! + + ); +} + +function SettingsScreen() { + return ( + + Settings! + + ); +} + +const Tab = createBottomTabNavigator(); + +export default function App() { + return ( + + + ( + { + const event = navigation.emit({ + type: 'tabPress', + target: route.key, + canPreventDefault: true, + }); + + if (event.defaultPrevented) { + preventDefault(); + } else { + navigation.dispatch({ + ...CommonActions.navigate(route.name, route.params), + target: state.key, + }); + } + }} + renderIcon={({ route, focused, color }) => + descriptors[route.key].options.tabBarIcon?.({ + focused, + color, + size: 24, + }) || null + } + getLabelText={({ route }) => { + const { options } = descriptors[route.key]; + const label = + typeof options.tabBarLabel === 'string' + ? options.tabBarLabel + : typeof options.title === 'string' + ? options.title + : route.name; + + return label; + }} + /> + )}> + ( + + ), + }} + /> + ( + + ), + }} + /> + + + + ); +} +`; + +module.exports = { + staticCode, + dynamicCode, +}; diff --git a/example/package.json b/example/package.json index 1fa8e61959..eb785c7900 100644 --- a/example/package.json +++ b/example/package.json @@ -19,10 +19,10 @@ "@pchmn/expo-material3-theme": "^1.3.2", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-masked-view/masked-view": "0.3.2", - "@react-navigation/bottom-tabs": "^6.6.1", - "@react-navigation/drawer": "^6.7.2", - "@react-navigation/native": "^6.1.18", - "@react-navigation/stack": "^6.4.1", + "@react-navigation/bottom-tabs": "^7.3.10", + "@react-navigation/drawer": "^7.3.9", + "@react-navigation/native": "^7.1.6", + "@react-navigation/stack": "^7.2.10", "expo": "^52.0.0", "expo-crypto": "~14.0.1", "expo-dev-client": "~5.0.4", diff --git a/example/src/ExampleList.tsx b/example/src/ExampleList.tsx index 3fc4483c63..9ac7c0ae34 100644 --- a/example/src/ExampleList.tsx +++ b/example/src/ExampleList.tsx @@ -28,7 +28,6 @@ import ListAccordionExample from './Examples/ListAccordionExample'; import ListAccordionExampleGroup from './Examples/ListAccordionGroupExample'; import ListItemExample from './Examples/ListItemExample'; import ListSectionExample from './Examples/ListSectionExample'; -import MaterialBottomTabNavigatorExample from './Examples/MaterialBottomTabNavigatorExample'; import MenuExample from './Examples/MenuExample'; import ProgressBarExample from './Examples/ProgressBarExample'; import RadioButtonExample from './Examples/RadioButtonExample'; @@ -80,7 +79,6 @@ export const mainExamples: Record< listAccordionGroup: ListAccordionExampleGroup, listSection: ListSectionExample, listItem: ListItemExample, - materialBottomTabNavigator: MaterialBottomTabNavigatorExample, menu: MenuExample, progressbar: ProgressBarExample, radio: RadioButtonExample, diff --git a/example/src/Examples/MaterialBottomTabNavigatorExample.tsx b/example/src/Examples/MaterialBottomTabNavigatorExample.tsx deleted file mode 100644 index cdddeb8369..0000000000 --- a/example/src/Examples/MaterialBottomTabNavigatorExample.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; - -import Icon from '@expo/vector-icons/MaterialCommunityIcons'; - -import { createMaterialBottomTabNavigator } from '../../../src/react-navigation'; - -const Tab = createMaterialBottomTabNavigator(); - -export default function MaterialBottomTabNavigatorExample() { - return ( - - ( - - ), - }} - /> - ( - - ), - }} - /> - ( - - ), - }} - /> - - ); -} - -MaterialBottomTabNavigatorExample.title = 'Material Bottom Tab Navigator'; - -function Feed() { - return ( - - Feed! - - ); -} - -function Profile() { - return ( - - Profile! - - ); -} - -function Notifications() { - return ( - - Notifications! - - ); -} - -const styles = StyleSheet.create({ - screen: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - // eslint-disable-next-line react-native/no-color-literals - tabs: { - backgroundColor: 'tomato', - }, -}); diff --git a/example/src/Examples/ThemingWithReactNavigation.tsx b/example/src/Examples/ThemingWithReactNavigation.tsx index acd9e67e9a..c4edf789ab 100644 --- a/example/src/Examples/ThemingWithReactNavigation.tsx +++ b/example/src/Examples/ThemingWithReactNavigation.tsx @@ -3,6 +3,7 @@ import { View, StyleSheet } from 'react-native'; import Icon from '@expo/vector-icons/MaterialCommunityIcons'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { PlatformPressable } from '@react-navigation/elements'; import { createStackNavigator } from '@react-navigation/stack'; import { Text } from 'react-native-paper'; @@ -30,6 +31,12 @@ const HomeTab = () => { ( + + ), }} > { function ThemingWithReactNavigation() { return ( - + ); diff --git a/example/src/RootNavigator.tsx b/example/src/RootNavigator.tsx index 49280dcff8..dee716b5c5 100644 --- a/example/src/RootNavigator.tsx +++ b/example/src/RootNavigator.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { Platform, StyleSheet, View } from 'react-native'; import type { DrawerNavigationProp } from '@react-navigation/drawer'; -import { getHeaderTitle } from '@react-navigation/elements'; import { CardStyleInterpolators, createStackNavigator, @@ -21,33 +20,25 @@ export default function Root() { return ( { - return { - detachPreviousScreen: !navigation.isFocused(), - cardStyleInterpolator, - header: ({ navigation, route, options, back }) => { - const title = getHeaderTitle(options, route.name); - return ( - - {back ? ( - navigation.goBack()} /> - ) : (navigation as any).openDrawer ? ( - - ( - navigation as any as DrawerNavigationProp<{}> - ).openDrawer() - } - /> - ) : null} - - - ); - }, - }; - }} + screenOptions={() => ({ + cardStyleInterpolator, + header: ({ navigation, route, options, back }) => ( + + {back ? ( + navigation.goBack()} /> + ) : (navigation as any).openDrawer ? ( + + (navigation as any as DrawerNavigationProp<{}>).openDrawer() + } + /> + ) : null} + + + ), + })} > - - - AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state)) - } - > - - {(insets) => { - const { left, right } = insets || { left: 0, right: 0 }; - const collapsedDrawerWidth = 80 + Math.max(left, right); - return ( - } - > - - - ); - }} - - - - + + AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state)) + } + > + + {(insets) => { + const { left, right } = insets || { left: 0, right: 0 }; + const collapsedDrawerWidth = 100 + Math.max(left, right); + return ( + } + > + + + ); + }} + + + ); diff --git a/example/src/index.tsx b/example/src/index.tsx index 750bc815c6..a330d90aca 100644 --- a/example/src/index.tsx +++ b/example/src/index.tsx @@ -22,6 +22,7 @@ import App from './RootNavigator'; import { CombinedDarkTheme, CombinedDefaultTheme, + createConfiguredFontNavigationTheme, createConfiguredFontTheme, } from '../utils/themes'; @@ -149,6 +150,8 @@ export default function PaperExample() { const combinedTheme = isDarkMode ? CombinedDarkTheme : CombinedDefaultTheme; const configuredFontTheme = createConfiguredFontTheme(combinedTheme); + const configuredFontNavigationTheme = + createConfiguredFontNavigationTheme(combinedTheme); return ( - - - AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state)) - } - > - - {(insets) => { - const { left, right } = insets || { left: 0, right: 0 }; - const collapsedDrawerWidth = 80 + Math.max(left, right); - return ( - } - > - - - ); - }} - - - + + AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state)) + } + > + + {(insets) => { + const { left, right } = insets || { left: 0, right: 0 }; + const collapsedDrawerWidth = 100 + Math.max(left, right); + return ( + } + > + + + ); + }} + + ); diff --git a/example/utils/themes.ts b/example/utils/themes.ts index 4c3c664f63..85e4bb4f81 100644 --- a/example/utils/themes.ts +++ b/example/utils/themes.ts @@ -21,6 +21,10 @@ export const CombinedDefaultTheme = { ...MD3LightTheme.colors, ...LightTheme.colors, }, + fonts: { + ...MD3LightTheme.fonts, + ...LightTheme.fonts, + }, }; export const CombinedDarkTheme = { @@ -30,6 +34,10 @@ export const CombinedDarkTheme = { ...MD3DarkTheme.colors, ...DarkTheme.colors, }, + fonts: { + ...MD3DarkTheme.fonts, + ...DarkTheme.fonts, + }, }; type CombinedTheme = typeof CombinedDefaultTheme; @@ -42,3 +50,26 @@ export const createConfiguredFontTheme = (theme: CombinedTheme) => ({ }, }), }); + +export const createConfiguredFontNavigationTheme = (theme: CombinedTheme) => ({ + ...theme, + fonts: { + ...theme.fonts, + regular: { + ...theme.fonts.regular, + fontFamily: 'Abel', + }, + medium: { + ...theme.fonts.medium, + fontFamily: 'Abel', + }, + heavy: { + ...theme.fonts.heavy, + fontFamily: 'Abel', + }, + bold: { + ...theme.fonts.bold, + fontFamily: 'Abel', + }, + }, +}); diff --git a/example/yarn.lock b/example/yarn.lock index 25e62483a9..348598e6c1 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -2735,109 +2735,116 @@ __metadata: languageName: node linkType: hard -"@react-navigation/bottom-tabs@npm:^6.6.1": - version: 6.6.1 - resolution: "@react-navigation/bottom-tabs@npm:6.6.1" +"@react-navigation/bottom-tabs@npm:^7.3.10": + version: 7.3.10 + resolution: "@react-navigation/bottom-tabs@npm:7.3.10" dependencies: - "@react-navigation/elements": "npm:^1.3.31" + "@react-navigation/elements": "npm:^2.3.8" color: "npm:^4.2.3" - warn-once: "npm:^0.1.0" peerDependencies: - "@react-navigation/native": ^6.0.0 - react: "*" + "@react-navigation/native": ^7.1.6 + react: ">= 18.2.0" react-native: "*" - react-native-safe-area-context: ">= 3.0.0" - react-native-screens: ">= 3.0.0" - checksum: 10c0/871bd824f8aa210718d8bfdc875cc840dbaeec86da67846cd34de8bbccfff837c7d825e257d2b0b5762b38f01ea785f95c54001e08e086fe7ea9234fefaec21f + react-native-safe-area-context: ">= 4.0.0" + react-native-screens: ">= 4.0.0" + checksum: 10c0/17adb7ebc38fd6d99866cf365f93099e5e83efdc0203051f3bbd7f731791f04c4323901d81ea2af9bb82a7ad22ff547d8a31f395a19de6160b7a3596990b1191 languageName: node linkType: hard -"@react-navigation/core@npm:^6.4.17": - version: 6.4.17 - resolution: "@react-navigation/core@npm:6.4.17" +"@react-navigation/core@npm:^7.8.5": + version: 7.8.5 + resolution: "@react-navigation/core@npm:7.8.5" dependencies: - "@react-navigation/routers": "npm:^6.1.9" + "@react-navigation/routers": "npm:^7.3.5" escape-string-regexp: "npm:^4.0.0" - nanoid: "npm:^3.1.23" + nanoid: "npm:3.3.8" query-string: "npm:^7.1.3" - react-is: "npm:^16.13.0" + react-is: "npm:^18.2.0" use-latest-callback: "npm:^0.2.1" + use-sync-external-store: "npm:^1.2.2" peerDependencies: - react: "*" - checksum: 10c0/f71fc10dd34d0bd13abd9c947833b9f5ac6aa18af58f74aa72bac45a5d348a4881924fec6534e7694d7084d940d7dac368a1b1fe7d86b260ff5cf475498e9d1b + react: ">= 18.2.0" + checksum: 10c0/3c26d39cd1186a8a78805b6a19e9fcea9747b6c0fdeb470b5aced0dc56cd209040880a874df71731cb4b426b31aa6e4efb0e9d3ced0b52009afc5676352f7bb7 languageName: node linkType: hard -"@react-navigation/drawer@npm:^6.7.2": - version: 6.7.2 - resolution: "@react-navigation/drawer@npm:6.7.2" +"@react-navigation/drawer@npm:^7.3.9": + version: 7.3.9 + resolution: "@react-navigation/drawer@npm:7.3.9" dependencies: - "@react-navigation/elements": "npm:^1.3.31" + "@react-navigation/elements": "npm:^2.3.8" color: "npm:^4.2.3" - warn-once: "npm:^0.1.0" + react-native-drawer-layout: "npm:^4.1.6" + use-latest-callback: "npm:^0.2.1" peerDependencies: - "@react-navigation/native": ^6.0.0 - react: "*" + "@react-navigation/native": ^7.1.6 + react: ">= 18.2.0" react-native: "*" - react-native-gesture-handler: ">= 1.0.0" - react-native-reanimated: ">= 1.0.0" - react-native-safe-area-context: ">= 3.0.0" - react-native-screens: ">= 3.0.0" - checksum: 10c0/33d0e1b84b2b630f516d27553a12465a6b28576b79293976200c8da1c3a08ec315c59fbb3a337e8ed736715316e61526c4b0914e35c36449fb4478d7db074282 + react-native-gesture-handler: ">= 2.0.0" + react-native-reanimated: ">= 2.0.0" + react-native-safe-area-context: ">= 4.0.0" + react-native-screens: ">= 4.0.0" + checksum: 10c0/00a793c69628b62e946f1b7f427e9bffcf9cb56793f0990750e045a313bb76997158b03b3161b6f79daf419fc436c82dfbbe438440fa13af367214247bc24b41 languageName: node linkType: hard -"@react-navigation/elements@npm:^1.3.31": - version: 1.3.31 - resolution: "@react-navigation/elements@npm:1.3.31" +"@react-navigation/elements@npm:^2.3.8": + version: 2.3.8 + resolution: "@react-navigation/elements@npm:2.3.8" + dependencies: + color: "npm:^4.2.3" peerDependencies: - "@react-navigation/native": ^6.0.0 - react: "*" + "@react-native-masked-view/masked-view": ">= 0.2.0" + "@react-navigation/native": ^7.1.6 + react: ">= 18.2.0" react-native: "*" - react-native-safe-area-context: ">= 3.0.0" - checksum: 10c0/4a2e6ee67d1954e8424c437fce83c6268cfa8bea22b1a593b4bfe59ed69deeeba3a1d7285880b3b1b100ffe9b542a81e824cddb53550c4dcf6bd6c29ccb16b97 + react-native-safe-area-context: ">= 4.0.0" + peerDependenciesMeta: + "@react-native-masked-view/masked-view": + optional: true + checksum: 10c0/8fc053bc853f2c588f3275b891a1e06d2638881e785bfa0b5086d2c813a2577992eb91cc080a3d723779ce6d8fd21242eaffdd6ac8e474743c2788a93509d6d5 languageName: node linkType: hard -"@react-navigation/native@npm:^6.1.18": - version: 6.1.18 - resolution: "@react-navigation/native@npm:6.1.18" +"@react-navigation/native@npm:^7.1.6": + version: 7.1.6 + resolution: "@react-navigation/native@npm:7.1.6" dependencies: - "@react-navigation/core": "npm:^6.4.17" + "@react-navigation/core": "npm:^7.8.5" escape-string-regexp: "npm:^4.0.0" fast-deep-equal: "npm:^3.1.3" - nanoid: "npm:^3.1.23" + nanoid: "npm:3.3.8" + use-latest-callback: "npm:^0.2.1" peerDependencies: - react: "*" + react: ">= 18.2.0" react-native: "*" - checksum: 10c0/1f7138da298067f537a22c5ab2e8e8529e83df8f87c5c61e84afdcd49d6ba1409f44a33bac3bd08bb11bcfba3f1c84574b7aa0a67b28531e4520d485bd4e3b9b + checksum: 10c0/f0f78885662bb20d48e31a9f7ffae24c90de43b1b902aee87ffe2e9e510e69d0417202e20f97077d41ab42170665eb4c2815a271758134701175ffe39374e166 languageName: node linkType: hard -"@react-navigation/routers@npm:^6.1.9": - version: 6.1.9 - resolution: "@react-navigation/routers@npm:6.1.9" +"@react-navigation/routers@npm:^7.3.5": + version: 7.3.5 + resolution: "@react-navigation/routers@npm:7.3.5" dependencies: - nanoid: "npm:^3.1.23" - checksum: 10c0/5b58014cf29bb71c7dc01201e271d55f0ecfe6d38d064179eeff0fc0b5cb739d4d9906eb133f100d25fc674c72c24aa65d5f6bfc3d036d79f7c5d1936391c605 + nanoid: "npm:3.3.8" + checksum: 10c0/f94f70391b5429707932a5c49014371815da20d715f15911c556bf606a8519d0f43382e0983c6c96cf2a40ddd8c2f8ecf38e33dcb9a65eb8cb02bdf377fccdd9 languageName: node linkType: hard -"@react-navigation/stack@npm:^6.4.1": - version: 6.4.1 - resolution: "@react-navigation/stack@npm:6.4.1" +"@react-navigation/stack@npm:^7.2.10": + version: 7.2.10 + resolution: "@react-navigation/stack@npm:7.2.10" dependencies: - "@react-navigation/elements": "npm:^1.3.31" + "@react-navigation/elements": "npm:^2.3.8" color: "npm:^4.2.3" - warn-once: "npm:^0.1.0" peerDependencies: - "@react-navigation/native": ^6.0.0 - react: "*" + "@react-navigation/native": ^7.1.6 + react: ">= 18.2.0" react-native: "*" - react-native-gesture-handler: ">= 1.0.0" - react-native-safe-area-context: ">= 3.0.0" - react-native-screens: ">= 3.0.0" - checksum: 10c0/6bc28e5e4e99161a538c1cb9752d70727704ca7b4137e71a44992dfe2ff6e0a3028353184424af1457ec59a4ea6ef9757fc99203280fd7339f36e61b80c9050a + react-native-gesture-handler: ">= 2.0.0" + react-native-safe-area-context: ">= 4.0.0" + react-native-screens: ">= 4.0.0" + checksum: 10c0/c73521b38c59bc723e7d9cbf30675c6032c23a02c0974737b9f7b479821f7e7a5378621833664cab2745efd923ac553d46f8566494ed02602bbf155e69ca95cb languageName: node linkType: hard @@ -8583,7 +8590,16 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.1.23, nanoid@npm:^3.3.6": +"nanoid@npm:3.3.8": + version: 3.3.8 + resolution: "nanoid@npm:3.3.8" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/4b1bb29f6cfebf3be3bc4ad1f1296fb0a10a3043a79f34fbffe75d1621b4318319211cd420549459018ea3592f0d2f159247a6f874911d6d26eaaadda2478120 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.6": version: 3.3.6 resolution: "nanoid@npm:3.3.6" bin: @@ -9915,7 +9931,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.0, react-is@npm:^16.13.1, react-is@npm:^16.7.0": +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 @@ -9929,6 +9945,27 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^18.2.0": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 + languageName: node + linkType: hard + +"react-native-drawer-layout@npm:^4.1.6": + version: 4.1.6 + resolution: "react-native-drawer-layout@npm:4.1.6" + dependencies: + use-latest-callback: "npm:^0.2.1" + peerDependencies: + react: ">= 18.2.0" + react-native: "*" + react-native-gesture-handler: ">= 2.0.0" + react-native-reanimated: ">= 2.0.0" + checksum: 10c0/d3089dbcf0fa418d7f675b4c41bd8a10e4a866e73c3b2f3b716baa50876ab4329107f6caa3543331d3ce55edc8767024965b890fbd26893e88e291b27d952c2e + languageName: node + linkType: hard + "react-native-gesture-handler@npm:~2.20.2": version: 2.20.2 resolution: "react-native-gesture-handler@npm:2.20.2" @@ -9954,10 +9991,10 @@ __metadata: "@pchmn/expo-material3-theme": "npm:^1.3.2" "@react-native-async-storage/async-storage": "npm:1.23.1" "@react-native-masked-view/masked-view": "npm:0.3.2" - "@react-navigation/bottom-tabs": "npm:^6.6.1" - "@react-navigation/drawer": "npm:^6.7.2" - "@react-navigation/native": "npm:^6.1.18" - "@react-navigation/stack": "npm:^6.4.1" + "@react-navigation/bottom-tabs": "npm:^7.3.10" + "@react-navigation/drawer": "npm:^7.3.9" + "@react-navigation/native": "npm:^7.1.6" + "@react-navigation/stack": "npm:^7.2.10" babel-plugin-module-resolver: "npm:^5.0.0" babel-preset-expo: "npm:~12.0.0" expo: "npm:^52.0.0" @@ -11817,6 +11854,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.2.2": + version: 1.5.0 + resolution: "use-sync-external-store@npm:1.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/1b8663515c0be34fa653feb724fdcce3984037c78dd4a18f68b2c8be55cc1a1084c578d5b75f158d41b5ddffc2bf5600766d1af3c19c8e329bb20af2ec6f52f4 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" diff --git a/package.json b/package.json index e55d84949c..e67199dba7 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "__fixtures__\\/[^/]+\\/(output|error)\\.js" ], "transformIgnorePatterns": [ - "node_modules/(?!(@react-native|react-native(-.*)?)/)" + "node_modules/(?!(@react-navigation|@react-native|react-native(-.*)?)/)" ] }, "greenkeeper": { diff --git a/src/components/BottomNavigation/BottomNavigationBar.tsx b/src/components/BottomNavigation/BottomNavigationBar.tsx index b782560537..1453b07ebf 100644 --- a/src/components/BottomNavigation/BottomNavigationBar.tsx +++ b/src/components/BottomNavigation/BottomNavigationBar.tsx @@ -248,112 +248,68 @@ const Touchable = ({ * A navigation bar which can easily be integrated with [React Navigation's Bottom Tabs Navigator](https://reactnavigation.org/docs/bottom-tab-navigator/). * * ## Usage + * ### without React Navigation * ```js * import React from 'react'; - * import { View, StyleSheet } from 'react-native'; - * - * import { CommonActions } from '@react-navigation/native'; - * import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; - * import { Text, BottomNavigation } from 'react-native-paper'; - * import Icon from '@react-native-vector-icons/material-design-icons'; - * - * const Tab = createBottomTabNavigator(); - * - * export default function MyComponent() { - * return ( - * ( - * { - * const event = navigation.emit({ - * type: 'tabPress', - * target: route.key, - * canPreventDefault: true, - * }); - * - * if (event.defaultPrevented) { - * preventDefault(); - * } else { - * navigation.dispatch({ - * ...CommonActions.navigate(route.name, route.params), - * target: state.key, - * }); - * } - * }} - * renderIcon={({ route, focused, color }) => { - * const { options } = descriptors[route.key]; - * if (options.tabBarIcon) { - * return options.tabBarIcon({ focused, color, size: 24 }); - * } - * - * return null; - * }} - * getLabelText={({ route }) => { - * const { options } = descriptors[route.key]; - * const label = - * typeof options.tabBarLabel === 'string' - * ? options.tabBarLabel - * : typeof options.title === 'string' - * ? options.title - * : route.name; - * - * return label; - * }} - * /> - * )} - * > - * { - * return ; - * }, - * }} - * /> - * { - * return ; - * }, - * }} - * /> - * - * ); - * } + * import { useState } from 'react'; + * import { View } from 'react-native'; + * import { BottomNavigation, Text, Provider } from 'react-native-paper'; + * import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'; * * function HomeScreen() { * return ( - * - * Home! + * + * Home! * * ); * } * * function SettingsScreen() { * return ( - * - * Settings! - * + * + * Settings! + * * ); * } * - * const styles = StyleSheet.create({ - * container: { - * flex: 1, - * justifyContent: 'center', - * alignItems: 'center', - * }, - * }); + * export default function MyComponent() { + * const [index, setIndex] = useState(0); + * + * const routes = [ + * { key: 'home', title: 'Home', icon: 'home' }, + * { key: 'settings', title: 'Settings', icon: 'cog' }, + * ]; + + * const renderScene = ({ route }) => { + * switch (route.key) { + * case 'home': + * return ; + * case 'settings': + * return ; + * default: + * return null; + * } + * }; + * + * return ( + * + * {renderScene({ route: routes[index] })} + * { + * const newIndex = routes.findIndex((r) => r.key === route.key); + * if (newIndex !== -1) { + * setIndex(newIndex); + * } + * }} + * renderIcon={({ route, color }) => ( + * + * )} + * getLabelText={({ route }) => route.title} + * /> + * + * ); + * } * ``` */ const BottomNavigationBar = ({ diff --git a/src/react-navigation/navigators/createMaterialBottomTabNavigator.tsx b/src/react-navigation/navigators/createMaterialBottomTabNavigator.tsx index 975b83172b..7b162554b3 100644 --- a/src/react-navigation/navigators/createMaterialBottomTabNavigator.tsx +++ b/src/react-navigation/navigators/createMaterialBottomTabNavigator.tsx @@ -64,6 +64,10 @@ function MaterialBottomTabNavigator({ ); } +/** + * @deprecated `createMaterialBottomTabNavigator` has been deprecated since `react-native-paper@5.14.0`. + * Please use `@react-navigation/bottom-tabs` version `7.x` or higher and combine it with `BottomNavigation.Bar` for a Material Design look. + */ export default createNavigatorFactory< TabNavigationState, MaterialBottomTabNavigationOptions, diff --git a/yarn.lock b/yarn.lock index 8f93e9c82c..aa7fc47de0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3779,34 +3779,34 @@ __metadata: languageName: node linkType: hard -"@react-navigation/core@npm:^6.4.9": - version: 6.4.9 - resolution: "@react-navigation/core@npm:6.4.9" +"@react-navigation/core@npm:^6.4.17": + version: 6.4.17 + resolution: "@react-navigation/core@npm:6.4.17" dependencies: "@react-navigation/routers": "npm:^6.1.9" escape-string-regexp: "npm:^4.0.0" nanoid: "npm:^3.1.23" query-string: "npm:^7.1.3" react-is: "npm:^16.13.0" - use-latest-callback: "npm:^0.1.5" + use-latest-callback: "npm:^0.2.1" peerDependencies: react: "*" - checksum: 10c0/31b77d026a6064712ef275e66c891c6eaf82c6494b96391ba839dad99c40dd2635921ebab8af0a4df71042f889d7165695124f751804ce16012182573139c255 + checksum: 10c0/f71fc10dd34d0bd13abd9c947833b9f5ac6aa18af58f74aa72bac45a5d348a4881924fec6534e7694d7084d940d7dac368a1b1fe7d86b260ff5cf475498e9d1b languageName: node linkType: hard "@react-navigation/native@npm:^6.1.2": - version: 6.1.7 - resolution: "@react-navigation/native@npm:6.1.7" + version: 6.1.18 + resolution: "@react-navigation/native@npm:6.1.18" dependencies: - "@react-navigation/core": "npm:^6.4.9" + "@react-navigation/core": "npm:^6.4.17" escape-string-regexp: "npm:^4.0.0" fast-deep-equal: "npm:^3.1.3" nanoid: "npm:^3.1.23" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/d1f6bc00782c8c40bc8a471fde7240cab41e627f7e4bba060aff118abc0496df006f2354a6d3a896cfc8048bbacb71eb682677ff9a3b5649e22efbe4b04e6bfe + checksum: 10c0/1f7138da298067f537a22c5ab2e8e8529e83df8f87c5c61e84afdcd49d6ba1409f44a33bac3bd08bb11bcfba3f1c84574b7aa0a67b28531e4520d485bd4e3b9b languageName: node linkType: hard @@ -11754,11 +11754,11 @@ __metadata: linkType: hard "nanoid@npm:^3.1.23": - version: 3.3.6 - resolution: "nanoid@npm:3.3.6" + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" bin: nanoid: bin/nanoid.cjs - checksum: 10c0/606b355960d0fcbe3d27924c4c52ef7d47d3b57208808ece73279420d91469b01ec1dce10fae512b6d4a8c5a5432b352b228336a8b2202a6ea68e67fa348e2ee + checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b languageName: node linkType: hard @@ -15390,16 +15390,7 @@ __metadata: languageName: node linkType: hard -"use-latest-callback@npm:^0.1.5": - version: 0.1.6 - resolution: "use-latest-callback@npm:0.1.6" - peerDependencies: - react: ">=16.8" - checksum: 10c0/514604ad33cb2f040ad3ece8ee787cc549ec92135ee12ebc6857bb309eeacf5d66426b3b94089842e8215a252d5ca6f04b059387f681688fb70ac37b238209f9 - languageName: node - linkType: hard - -"use-latest-callback@npm:^0.2.3": +"use-latest-callback@npm:^0.2.1, use-latest-callback@npm:^0.2.3": version: 0.2.3 resolution: "use-latest-callback@npm:0.2.3" peerDependencies: