- React Navigation is built by Expo ,{' '}
- Software Mansion , and{' '}
- Callstack , with contributions
- from the{' '}
+ React Navigation relies on the support from the community. Thanks to{' '}
+ Software Mansion ,{' '}
+ Callstack ,{' '}
+ Expo , and our amazing{' '}
- community
+ contributors
{' '}
- and{' '}
- sponsors :
+ & sponsors :
{sponsors.map((sponsor) => (
diff --git a/src/pages/index.js b/src/pages/index.js
index fc18c8b5089..9ad7899c428 100755
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -1,12 +1,10 @@
-import React from 'react';
-import Layout from '@theme/Layout';
-import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
-import useBaseUrl from '@docusaurus/useBaseUrl';
-import sponsors from '../data/sponsors';
+import Layout from '@theme/Layout';
+import React from 'react';
-import Splash from './home/Splash';
import Features from './home/Features';
+import Footer from './home/Footer';
+import Splash from './home/Splash';
import Sponsors from './home/Sponsors';
const features = [
@@ -44,10 +42,15 @@ function Home() {
const { siteConfig = {} } = context;
return (
-
+
+
);
}
diff --git a/src/plugins/disable-fully-specified.mjs b/src/plugins/disable-fully-specified.mjs
new file mode 100644
index 00000000000..031a96df5ca
--- /dev/null
+++ b/src/plugins/disable-fully-specified.mjs
@@ -0,0 +1,19 @@
+export default function disableFullySpecified(context, options) {
+ return {
+ name: 'disable-fully-specified',
+ configureWebpack() {
+ return {
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ resolve: {
+ fullySpecified: false,
+ },
+ },
+ ],
+ },
+ };
+ },
+ };
+}
diff --git a/src/plugins/react-navigation-versions.mjs b/src/plugins/react-navigation-versions.mjs
new file mode 100644
index 00000000000..7b3c257038a
--- /dev/null
+++ b/src/plugins/react-navigation-versions.mjs
@@ -0,0 +1,80 @@
+import { mkdir, readFile, writeFile } from 'node:fs/promises';
+import { dirname, join } from 'node:path';
+
+const CACHE_DIR = join(
+ process.cwd(),
+ 'node_modules',
+ '.cache',
+ 'react-navigation-versions'
+);
+
+const query = async (name, tag) => {
+ const cached = join(CACHE_DIR, `${name}-${tag}.json`);
+
+ let pkg;
+
+ try {
+ pkg = await fetch(`https://registry.npmjs.org/${name}/${tag}`).then((res) =>
+ res.json()
+ );
+
+ await mkdir(dirname(cached), { recursive: true });
+ await writeFile(cached, JSON.stringify(pkg));
+ } catch (e) {
+ const data = await readFile(cached, 'utf-8');
+
+ pkg = JSON.parse(data);
+ }
+
+ return pkg;
+};
+
+export default function reactNavigationVersionsPlugin(context, options) {
+ return {
+ name: 'react-navigation-versions',
+ async contentLoaded({ content, actions }) {
+ const queries = {
+ '7.x': {
+ tag: 'latest',
+ packages: [
+ '@react-navigation/bottom-tabs',
+ '@react-navigation/core',
+ '@react-navigation/drawer',
+ '@react-navigation/elements',
+ '@react-navigation/material-top-tabs',
+ '@react-navigation/native-stack',
+ '@react-navigation/native',
+ '@react-navigation/routers',
+ '@react-navigation/stack',
+ 'react-native-drawer-layout',
+ 'react-native-tab-view',
+ ],
+ },
+ };
+
+ const versions = Object.fromEntries(
+ await Promise.all(
+ Object.entries(queries).map(async ([version, { tag, packages }]) => {
+ const items = await Promise.all(
+ packages.map(async (name) => {
+ const pkg = await query(name, tag);
+ const peers = Object.fromEntries(
+ Object.entries(pkg.peerDependencies || {}).map(([name]) => [
+ name,
+ '*',
+ ])
+ );
+
+ return [name, [pkg.version, peers]];
+ })
+ );
+
+ return [version, Object.fromEntries(items)];
+ })
+ )
+ );
+
+ actions.setGlobalData({ versions });
+ },
+ };
+}
diff --git a/static/assets/7.x/bottom-tabs-fade.mp4 b/static/assets/7.x/bottom-tabs-fade.mp4
new file mode 100644
index 00000000000..07b261b2788
Binary files /dev/null and b/static/assets/7.x/bottom-tabs-fade.mp4 differ
diff --git a/static/assets/7.x/bottom-tabs-shift.mp4 b/static/assets/7.x/bottom-tabs-shift.mp4
new file mode 100644
index 00000000000..1a0cb301b86
Binary files /dev/null and b/static/assets/7.x/bottom-tabs-shift.mp4 differ
diff --git a/static/assets/7.x/bottom-tabs-side-compact.png b/static/assets/7.x/bottom-tabs-side-compact.png
new file mode 100644
index 00000000000..5217d8ac77d
Binary files /dev/null and b/static/assets/7.x/bottom-tabs-side-compact.png differ
diff --git a/static/assets/7.x/bottom-tabs-side-material.png b/static/assets/7.x/bottom-tabs-side-material.png
new file mode 100644
index 00000000000..9016f94cdfe
Binary files /dev/null and b/static/assets/7.x/bottom-tabs-side-material.png differ
diff --git a/static/assets/7.x/bottom-tabs-side.png b/static/assets/7.x/bottom-tabs-side.png
new file mode 100644
index 00000000000..9a0fdc7cac7
Binary files /dev/null and b/static/assets/7.x/bottom-tabs-side.png differ
diff --git a/static/assets/7.x/bottom-tabs.mp4 b/static/assets/7.x/bottom-tabs.mp4
new file mode 100644
index 00000000000..ed4d3992cdd
Binary files /dev/null and b/static/assets/7.x/bottom-tabs.mp4 differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarActiveTintColor.png b/static/assets/7.x/bottom-tabs/tabBarActiveTintColor.png
new file mode 100644
index 00000000000..e9b274fc92a
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarActiveTintColor.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarBackground.png b/static/assets/7.x/bottom-tabs/tabBarBackground.png
new file mode 100644
index 00000000000..650838f1468
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarBackground.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarBadge.png b/static/assets/7.x/bottom-tabs/tabBarBadge.png
new file mode 100644
index 00000000000..e04963dfbcb
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarBadge.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarBadgeStyle.png b/static/assets/7.x/bottom-tabs/tabBarBadgeStyle.png
new file mode 100644
index 00000000000..2b406d9c5e2
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarBadgeStyle.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarInactiveTintColor.png b/static/assets/7.x/bottom-tabs/tabBarInactiveTintColor.png
new file mode 100644
index 00000000000..b6c7aa3c22e
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarInactiveTintColor.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarLabelPosition-below.png b/static/assets/7.x/bottom-tabs/tabBarLabelPosition-below.png
new file mode 100644
index 00000000000..9b5924cd897
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarLabelPosition-below.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarLabelPosition-beside.png b/static/assets/7.x/bottom-tabs/tabBarLabelPosition-beside.png
new file mode 100644
index 00000000000..3be06ede805
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarLabelPosition-beside.png differ
diff --git a/static/assets/7.x/bottom-tabs/tabBarLabelStyle.png b/static/assets/7.x/bottom-tabs/tabBarLabelStyle.png
new file mode 100644
index 00000000000..74d7c3f848b
Binary files /dev/null and b/static/assets/7.x/bottom-tabs/tabBarLabelStyle.png differ
diff --git a/static/assets/7.x/devtool-logger.mp4 b/static/assets/7.x/devtool-logger.mp4
new file mode 100644
index 00000000000..7a6073f8b1c
Binary files /dev/null and b/static/assets/7.x/devtool-logger.mp4 differ
diff --git a/static/assets/7.x/drawer-layout.mp4 b/static/assets/7.x/drawer-layout.mp4
new file mode 100644
index 00000000000..ff076ec0045
Binary files /dev/null and b/static/assets/7.x/drawer-layout.mp4 differ
diff --git a/static/assets/7.x/drawer.mp4 b/static/assets/7.x/drawer.mp4
new file mode 100644
index 00000000000..5277da8d162
Binary files /dev/null and b/static/assets/7.x/drawer.mp4 differ
diff --git a/static/assets/7.x/drawer/drawerActiveBackgroundColor.png b/static/assets/7.x/drawer/drawerActiveBackgroundColor.png
new file mode 100644
index 00000000000..3340babed15
Binary files /dev/null and b/static/assets/7.x/drawer/drawerActiveBackgroundColor.png differ
diff --git a/static/assets/7.x/drawer/drawerActiveTintColor.png b/static/assets/7.x/drawer/drawerActiveTintColor.png
new file mode 100644
index 00000000000..5ebfb044b12
Binary files /dev/null and b/static/assets/7.x/drawer/drawerActiveTintColor.png differ
diff --git a/static/assets/7.x/drawer/drawerItemStyle.png b/static/assets/7.x/drawer/drawerItemStyle.png
new file mode 100644
index 00000000000..72a239d365d
Binary files /dev/null and b/static/assets/7.x/drawer/drawerItemStyle.png differ
diff --git a/static/assets/7.x/drawer/drawerLabelStyle.png b/static/assets/7.x/drawer/drawerLabelStyle.png
new file mode 100644
index 00000000000..cbe5531ed8b
Binary files /dev/null and b/static/assets/7.x/drawer/drawerLabelStyle.png differ
diff --git a/static/assets/7.x/drawer/drawerStatusBarAnimation-fade.mp4 b/static/assets/7.x/drawer/drawerStatusBarAnimation-fade.mp4
new file mode 100644
index 00000000000..4945278107f
Binary files /dev/null and b/static/assets/7.x/drawer/drawerStatusBarAnimation-fade.mp4 differ
diff --git a/static/assets/7.x/drawer/drawerStatusBarAnimation-slide.mp4 b/static/assets/7.x/drawer/drawerStatusBarAnimation-slide.mp4
new file mode 100644
index 00000000000..c26696e06dc
Binary files /dev/null and b/static/assets/7.x/drawer/drawerStatusBarAnimation-slide.mp4 differ
diff --git a/static/assets/7.x/drawer/drawerStyle.png b/static/assets/7.x/drawer/drawerStyle.png
new file mode 100644
index 00000000000..6a0f1de808a
Binary files /dev/null and b/static/assets/7.x/drawer/drawerStyle.png differ
diff --git a/static/assets/7.x/drawer/drawerType-back.mp4 b/static/assets/7.x/drawer/drawerType-back.mp4
new file mode 100644
index 00000000000..e4a6b03922b
Binary files /dev/null and b/static/assets/7.x/drawer/drawerType-back.mp4 differ
diff --git a/static/assets/7.x/drawer/drawerType-front.mp4 b/static/assets/7.x/drawer/drawerType-front.mp4
new file mode 100644
index 00000000000..3dcf3f70e0b
Binary files /dev/null and b/static/assets/7.x/drawer/drawerType-front.mp4 differ
diff --git a/static/assets/7.x/drawer/drawerType-masterDetail.mp4 b/static/assets/7.x/drawer/drawerType-masterDetail.mp4
new file mode 100644
index 00000000000..0fa4718b9a9
Binary files /dev/null and b/static/assets/7.x/drawer/drawerType-masterDetail.mp4 differ
diff --git a/static/assets/7.x/drawer/drawerType-slide.mp4 b/static/assets/7.x/drawer/drawerType-slide.mp4
new file mode 100644
index 00000000000..02975a99f28
Binary files /dev/null and b/static/assets/7.x/drawer/drawerType-slide.mp4 differ
diff --git a/static/assets/7.x/drawer/overlayColor.mp4 b/static/assets/7.x/drawer/overlayColor.mp4
new file mode 100644
index 00000000000..7d58fa28b13
Binary files /dev/null and b/static/assets/7.x/drawer/overlayColor.mp4 differ
diff --git a/static/assets/7.x/material-top-tabs.mp4 b/static/assets/7.x/material-top-tabs.mp4
new file mode 100644
index 00000000000..5717c365909
Binary files /dev/null and b/static/assets/7.x/material-top-tabs.mp4 differ
diff --git a/static/assets/7.x/native-bottom-tabs-android.mp4 b/static/assets/7.x/native-bottom-tabs-android.mp4
new file mode 100644
index 00000000000..4c65cf2105c
Binary files /dev/null and b/static/assets/7.x/native-bottom-tabs-android.mp4 differ
diff --git a/static/assets/7.x/native-bottom-tabs-ios-minimize.mp4 b/static/assets/7.x/native-bottom-tabs-ios-minimize.mp4
new file mode 100644
index 00000000000..2460652d08b
Binary files /dev/null and b/static/assets/7.x/native-bottom-tabs-ios-minimize.mp4 differ
diff --git a/static/assets/7.x/native-bottom-tabs-ios-search.mp4 b/static/assets/7.x/native-bottom-tabs-ios-search.mp4
new file mode 100644
index 00000000000..e3892bde2f3
Binary files /dev/null and b/static/assets/7.x/native-bottom-tabs-ios-search.mp4 differ
diff --git a/static/assets/7.x/native-bottom-tabs-ios.mp4 b/static/assets/7.x/native-bottom-tabs-ios.mp4
new file mode 100644
index 00000000000..29f928e9779
Binary files /dev/null and b/static/assets/7.x/native-bottom-tabs-ios.mp4 differ
diff --git a/static/assets/7.x/native-stack-android.mp4 b/static/assets/7.x/native-stack-android.mp4
new file mode 100644
index 00000000000..7483dcd8f81
Binary files /dev/null and b/static/assets/7.x/native-stack-android.mp4 differ
diff --git a/static/assets/7.x/native-stack-ios.mp4 b/static/assets/7.x/native-stack-ios.mp4
new file mode 100644
index 00000000000..2eb1e2f4946
Binary files /dev/null and b/static/assets/7.x/native-stack-ios.mp4 differ
diff --git a/static/assets/7.x/native-stack/animationTypeForReplace-pop.mp4 b/static/assets/7.x/native-stack/animationTypeForReplace-pop.mp4
new file mode 100644
index 00000000000..eff41148ce0
Binary files /dev/null and b/static/assets/7.x/native-stack/animationTypeForReplace-pop.mp4 differ
diff --git a/static/assets/7.x/native-stack/animationTypeForReplace-push.mp4 b/static/assets/7.x/native-stack/animationTypeForReplace-push.mp4
new file mode 100644
index 00000000000..dc8a3488cd5
Binary files /dev/null and b/static/assets/7.x/native-stack/animationTypeForReplace-push.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetAllowedDetents.mp4 b/static/assets/7.x/native-stack/formSheet-sheetAllowedDetents.mp4
new file mode 100644
index 00000000000..25059f143c9
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetAllowedDetents.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetCornerRadius.mp4 b/static/assets/7.x/native-stack/formSheet-sheetCornerRadius.mp4
new file mode 100644
index 00000000000..6ebe5929e0e
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetCornerRadius.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetElevation.mp4 b/static/assets/7.x/native-stack/formSheet-sheetElevation.mp4
new file mode 100644
index 00000000000..a9d80dcde30
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetElevation.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetExpandsWhenScrolledToEdge.mp4 b/static/assets/7.x/native-stack/formSheet-sheetExpandsWhenScrolledToEdge.mp4
new file mode 100644
index 00000000000..2da3d6a74fa
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetExpandsWhenScrolledToEdge.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetGrabberVisible.mp4 b/static/assets/7.x/native-stack/formSheet-sheetGrabberVisible.mp4
new file mode 100644
index 00000000000..4d0c331cf23
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetGrabberVisible.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetInitialDetentIndex.mp4 b/static/assets/7.x/native-stack/formSheet-sheetInitialDetentIndex.mp4
new file mode 100644
index 00000000000..2484f912240
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetInitialDetentIndex.mp4 differ
diff --git a/static/assets/7.x/native-stack/formSheet-sheetLargestUndimmedDetentIndex.mp4 b/static/assets/7.x/native-stack/formSheet-sheetLargestUndimmedDetentIndex.mp4
new file mode 100644
index 00000000000..f7eb0cb7fee
Binary files /dev/null and b/static/assets/7.x/native-stack/formSheet-sheetLargestUndimmedDetentIndex.mp4 differ
diff --git a/static/assets/7.x/native-stack/headerBackButtonMenuEnabled.png b/static/assets/7.x/native-stack/headerBackButtonMenuEnabled.png
new file mode 100644
index 00000000000..4cc9e794ab0
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBackButtonMenuEnabled.png differ
diff --git a/static/assets/7.x/native-stack/headerBackTitle.jpeg b/static/assets/7.x/native-stack/headerBackTitle.jpeg
new file mode 100644
index 00000000000..587996408bd
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBackTitle.jpeg differ
diff --git a/static/assets/7.x/native-stack/headerBackTitleStyle.png b/static/assets/7.x/native-stack/headerBackTitleStyle.png
new file mode 100644
index 00000000000..2b83888656c
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBackTitleStyle.png differ
diff --git a/static/assets/7.x/native-stack/headerBackground.png b/static/assets/7.x/native-stack/headerBackground.png
new file mode 100644
index 00000000000..bd601236d1e
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBackground.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-dark.png b/static/assets/7.x/native-stack/headerBlurEffect-dark.png
new file mode 100644
index 00000000000..88da21ccbee
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-dark.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-light.png b/static/assets/7.x/native-stack/headerBlurEffect-light.png
new file mode 100644
index 00000000000..05293d0a790
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-light.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-prominent.png b/static/assets/7.x/native-stack/headerBlurEffect-prominent.png
new file mode 100644
index 00000000000..c6049585f97
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-prominent.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-regular.png b/static/assets/7.x/native-stack/headerBlurEffect-regular.png
new file mode 100644
index 00000000000..8c1891ec75f
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-regular.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterial.png b/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterial.png
new file mode 100644
index 00000000000..3da2f20198b
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterial.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterialDark.png b/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterialDark.png
new file mode 100644
index 00000000000..624ab4660b2
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterialDark.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterialLight.png b/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterialLight.png
new file mode 100644
index 00000000000..1ecca6cba51
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemChromeMaterialLight.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemMaterial.png b/static/assets/7.x/native-stack/headerBlurEffect-systemMaterial.png
new file mode 100644
index 00000000000..08dcb1a85b1
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemMaterial.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemMaterialDark.png b/static/assets/7.x/native-stack/headerBlurEffect-systemMaterialDark.png
new file mode 100644
index 00000000000..ea4bde41fcb
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemMaterialDark.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemMaterialLight.png b/static/assets/7.x/native-stack/headerBlurEffect-systemMaterialLight.png
new file mode 100644
index 00000000000..1210fce73d8
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemMaterialLight.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterial.png b/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterial.png
new file mode 100644
index 00000000000..e22a48720c7
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterial.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterialDark.png b/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterialDark.png
new file mode 100644
index 00000000000..71f4ffc18bf
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterialDark.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterialLight.png b/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterialLight.png
new file mode 100644
index 00000000000..47dcdcdee5d
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemThickMaterialLight.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterial.png b/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterial.png
new file mode 100644
index 00000000000..e43196b4f88
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterial.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterialDark.png b/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterialDark.png
new file mode 100644
index 00000000000..e041329c81e
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterialDark.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterialLight.png b/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterialLight.png
new file mode 100644
index 00000000000..a935bca521e
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemThinMaterialLight.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterial.png b/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterial.png
new file mode 100644
index 00000000000..b525154609d
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterial.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterialDark.png b/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterialDark.png
new file mode 100644
index 00000000000..5960598b817
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterialDark.png differ
diff --git a/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterialLight.png b/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterialLight.png
new file mode 100644
index 00000000000..bfe19277db7
Binary files /dev/null and b/static/assets/7.x/native-stack/headerBlurEffect-systemUltraThinMaterialLight.png differ
diff --git a/static/assets/7.x/native-stack/headerLargeStyle.mp4 b/static/assets/7.x/native-stack/headerLargeStyle.mp4
new file mode 100644
index 00000000000..9ff39788224
Binary files /dev/null and b/static/assets/7.x/native-stack/headerLargeStyle.mp4 differ
diff --git a/static/assets/7.x/native-stack/headerLargeTitle.mp4 b/static/assets/7.x/native-stack/headerLargeTitle.mp4
new file mode 100644
index 00000000000..a33e31cc5de
Binary files /dev/null and b/static/assets/7.x/native-stack/headerLargeTitle.mp4 differ
diff --git a/static/assets/7.x/native-stack/headerLargeTitleStyle.png b/static/assets/7.x/native-stack/headerLargeTitleStyle.png
new file mode 100644
index 00000000000..4722cb6c719
Binary files /dev/null and b/static/assets/7.x/native-stack/headerLargeTitleStyle.png differ
diff --git a/static/assets/7.x/native-stack/headerLeft.png b/static/assets/7.x/native-stack/headerLeft.png
new file mode 100644
index 00000000000..d46e1cc63cb
Binary files /dev/null and b/static/assets/7.x/native-stack/headerLeft.png differ
diff --git a/static/assets/7.x/native-stack/headerRight.png b/static/assets/7.x/native-stack/headerRight.png
new file mode 100644
index 00000000000..49af6766bdf
Binary files /dev/null and b/static/assets/7.x/native-stack/headerRight.png differ
diff --git a/static/assets/7.x/native-stack/headerSearchBarOptions-barTintColor.png b/static/assets/7.x/native-stack/headerSearchBarOptions-barTintColor.png
new file mode 100644
index 00000000000..2aedbec7805
Binary files /dev/null and b/static/assets/7.x/native-stack/headerSearchBarOptions-barTintColor.png differ
diff --git a/static/assets/7.x/native-stack/headerSearchBarOptions-headerIconColor.png b/static/assets/7.x/native-stack/headerSearchBarOptions-headerIconColor.png
new file mode 100644
index 00000000000..85b31a7d766
Binary files /dev/null and b/static/assets/7.x/native-stack/headerSearchBarOptions-headerIconColor.png differ
diff --git a/static/assets/7.x/native-stack/headerSearchBarOptions-hintTextColor.png b/static/assets/7.x/native-stack/headerSearchBarOptions-hintTextColor.png
new file mode 100644
index 00000000000..cbeacc6c3ac
Binary files /dev/null and b/static/assets/7.x/native-stack/headerSearchBarOptions-hintTextColor.png differ
diff --git a/static/assets/7.x/native-stack/headerSearchBarOptions-textColor.png b/static/assets/7.x/native-stack/headerSearchBarOptions-textColor.png
new file mode 100644
index 00000000000..f1f7cd2a4ba
Binary files /dev/null and b/static/assets/7.x/native-stack/headerSearchBarOptions-textColor.png differ
diff --git a/static/assets/7.x/native-stack/headerSearchBarOptions-tintColor.png b/static/assets/7.x/native-stack/headerSearchBarOptions-tintColor.png
new file mode 100644
index 00000000000..0f9a84bce27
Binary files /dev/null and b/static/assets/7.x/native-stack/headerSearchBarOptions-tintColor.png differ
diff --git a/static/assets/7.x/native-stack/headerShadowVisible-Android.png b/static/assets/7.x/native-stack/headerShadowVisible-Android.png
new file mode 100644
index 00000000000..c2c9429f282
Binary files /dev/null and b/static/assets/7.x/native-stack/headerShadowVisible-Android.png differ
diff --git a/static/assets/7.x/native-stack/headerShadowVisible-iOS.png b/static/assets/7.x/native-stack/headerShadowVisible-iOS.png
new file mode 100644
index 00000000000..ebbfe7c8667
Binary files /dev/null and b/static/assets/7.x/native-stack/headerShadowVisible-iOS.png differ
diff --git a/static/assets/7.x/native-stack/headerStyle.mp4 b/static/assets/7.x/native-stack/headerStyle.mp4
new file mode 100644
index 00000000000..1723abc731a
Binary files /dev/null and b/static/assets/7.x/native-stack/headerStyle.mp4 differ
diff --git a/static/assets/7.x/native-stack/headerTintColor.png b/static/assets/7.x/native-stack/headerTintColor.png
new file mode 100644
index 00000000000..7044179f71f
Binary files /dev/null and b/static/assets/7.x/native-stack/headerTintColor.png differ
diff --git a/static/assets/7.x/native-stack/headerTitleAlign-center.png b/static/assets/7.x/native-stack/headerTitleAlign-center.png
new file mode 100644
index 00000000000..36da4a8204e
Binary files /dev/null and b/static/assets/7.x/native-stack/headerTitleAlign-center.png differ
diff --git a/static/assets/7.x/native-stack/headerTitleAlign-left.png b/static/assets/7.x/native-stack/headerTitleAlign-left.png
new file mode 100644
index 00000000000..50d4e6c7ab8
Binary files /dev/null and b/static/assets/7.x/native-stack/headerTitleAlign-left.png differ
diff --git a/static/assets/7.x/native-stack/headerTitleStyle.png b/static/assets/7.x/native-stack/headerTitleStyle.png
new file mode 100644
index 00000000000..edf0ceb27c5
Binary files /dev/null and b/static/assets/7.x/native-stack/headerTitleStyle.png differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-default.mp4 b/static/assets/7.x/native-stack/native-stack-animation-default.mp4
new file mode 100644
index 00000000000..97297b0ef81
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-default.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-fade-from-bottom.mp4 b/static/assets/7.x/native-stack/native-stack-animation-fade-from-bottom.mp4
new file mode 100644
index 00000000000..cec56aa0a66
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-fade-from-bottom.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-fade.mp4 b/static/assets/7.x/native-stack/native-stack-animation-fade.mp4
new file mode 100644
index 00000000000..f87cb6159a8
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-fade.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-flip.mp4 b/static/assets/7.x/native-stack/native-stack-animation-flip.mp4
new file mode 100644
index 00000000000..bd459c0ccee
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-flip.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-none.mp4 b/static/assets/7.x/native-stack/native-stack-animation-none.mp4
new file mode 100644
index 00000000000..c4768eda32a
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-none.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-simple-push.mp4 b/static/assets/7.x/native-stack/native-stack-animation-simple-push.mp4
new file mode 100644
index 00000000000..89036741ec8
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-simple-push.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-slide-from-bottom.mp4 b/static/assets/7.x/native-stack/native-stack-animation-slide-from-bottom.mp4
new file mode 100644
index 00000000000..4ecdefef5e9
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-slide-from-bottom.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-slide-from-left.mp4 b/static/assets/7.x/native-stack/native-stack-animation-slide-from-left.mp4
new file mode 100644
index 00000000000..2af3b9bf4e4
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-slide-from-left.mp4 differ
diff --git a/static/assets/7.x/native-stack/native-stack-animation-slide-from-right.mp4 b/static/assets/7.x/native-stack/native-stack-animation-slide-from-right.mp4
new file mode 100644
index 00000000000..6184037ed99
Binary files /dev/null and b/static/assets/7.x/native-stack/native-stack-animation-slide-from-right.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-card.mp4 b/static/assets/7.x/native-stack/presentation-card.mp4
new file mode 100644
index 00000000000..4040ea8487c
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-card.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-containedModal.mp4 b/static/assets/7.x/native-stack/presentation-containedModal.mp4
new file mode 100644
index 00000000000..0cb4cba351d
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-containedModal.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-containedTransparentModal.mp4 b/static/assets/7.x/native-stack/presentation-containedTransparentModal.mp4
new file mode 100644
index 00000000000..3495fe32296
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-containedTransparentModal.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-formSheet-android.mp4 b/static/assets/7.x/native-stack/presentation-formSheet-android.mp4
new file mode 100644
index 00000000000..966bff508c7
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-formSheet-android.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-formSheet-ios.mp4 b/static/assets/7.x/native-stack/presentation-formSheet-ios.mp4
new file mode 100644
index 00000000000..89fca9b830e
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-formSheet-ios.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-fullScreenModal.mp4 b/static/assets/7.x/native-stack/presentation-fullScreenModal.mp4
new file mode 100644
index 00000000000..1b0262072d2
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-fullScreenModal.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-modal.mp4 b/static/assets/7.x/native-stack/presentation-modal.mp4
new file mode 100644
index 00000000000..58ba8739e04
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-modal.mp4 differ
diff --git a/static/assets/7.x/native-stack/presentation-transparentModal.mp4 b/static/assets/7.x/native-stack/presentation-transparentModal.mp4
new file mode 100644
index 00000000000..49ee088dacd
Binary files /dev/null and b/static/assets/7.x/native-stack/presentation-transparentModal.mp4 differ
diff --git a/static/assets/7.x/stack-android.mp4 b/static/assets/7.x/stack-android.mp4
new file mode 100644
index 00000000000..25cb6e78c04
Binary files /dev/null and b/static/assets/7.x/stack-android.mp4 differ
diff --git a/static/assets/7.x/stack-ios.mp4 b/static/assets/7.x/stack-ios.mp4
new file mode 100644
index 00000000000..63a81e742ce
Binary files /dev/null and b/static/assets/7.x/stack-ios.mp4 differ
diff --git a/static/assets/7.x/tab-view.mp4 b/static/assets/7.x/tab-view.mp4
new file mode 100644
index 00000000000..6e798feee7c
Binary files /dev/null and b/static/assets/7.x/tab-view.mp4 differ
diff --git a/static/assets/behavior/prevent-closing.mp4 b/static/assets/behavior/prevent-closing.mp4
new file mode 100644
index 00000000000..1119c57a7ea
Binary files /dev/null and b/static/assets/behavior/prevent-closing.mp4 differ
diff --git a/static/assets/blog/7.x/bottom-tabs-sidebar.png b/static/assets/blog/7.x/bottom-tabs-sidebar.png
new file mode 100644
index 00000000000..6a92f832993
Binary files /dev/null and b/static/assets/blog/7.x/bottom-tabs-sidebar.png differ
diff --git a/static/assets/blog/native-bottom-tabs/android.png b/static/assets/blog/native-bottom-tabs/android.png
new file mode 100644
index 00000000000..8ac1fcb0bc1
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/android.png differ
diff --git a/static/assets/blog/native-bottom-tabs/ios.png b/static/assets/blog/native-bottom-tabs/ios.png
new file mode 100644
index 00000000000..78792f1b4bc
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/ios.png differ
diff --git a/static/assets/blog/native-bottom-tabs/ipados.png b/static/assets/blog/native-bottom-tabs/ipados.png
new file mode 100644
index 00000000000..5804af44bfc
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/ipados.png differ
diff --git a/static/assets/blog/native-bottom-tabs/macos.png b/static/assets/blog/native-bottom-tabs/macos.png
new file mode 100644
index 00000000000..cb704aa3c7e
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/macos.png differ
diff --git a/static/assets/blog/native-bottom-tabs/result.png b/static/assets/blog/native-bottom-tabs/result.png
new file mode 100644
index 00000000000..dd62cdbc222
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/result.png differ
diff --git a/static/assets/blog/native-bottom-tabs/tvos.png b/static/assets/blog/native-bottom-tabs/tvos.png
new file mode 100644
index 00000000000..45e3840b5d8
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/tvos.png differ
diff --git a/static/assets/blog/native-bottom-tabs/visionos.png b/static/assets/blog/native-bottom-tabs/visionos.png
new file mode 100644
index 00000000000..4660c2769bb
Binary files /dev/null and b/static/assets/blog/native-bottom-tabs/visionos.png differ
diff --git a/static/assets/deep-linking/xcode-linking.png b/static/assets/deep-linking/xcode-linking.png
old mode 100755
new mode 100644
index 9f5170bf9a0..2cea12f4854
Binary files a/static/assets/deep-linking/xcode-linking.png and b/static/assets/deep-linking/xcode-linking.png differ
diff --git a/static/assets/header-items/header-items-menu.png b/static/assets/header-items/header-items-menu.png
new file mode 100644
index 00000000000..c900fdb84f7
Binary files /dev/null and b/static/assets/header-items/header-items-menu.png differ
diff --git a/static/assets/header-items/header-items.png b/static/assets/header-items/header-items.png
new file mode 100644
index 00000000000..cb7430b9128
Binary files /dev/null and b/static/assets/header-items/header-items.png differ
diff --git a/static/assets/headers/custom_headers.png b/static/assets/headers/custom_headers.png
old mode 100755
new mode 100644
index c84325e4277..6d25b50eabe
Binary files a/static/assets/headers/custom_headers.png and b/static/assets/headers/custom_headers.png differ
diff --git a/static/assets/headers/header-back-custom.png b/static/assets/headers/header-back-custom.png
new file mode 100644
index 00000000000..377815032ce
Binary files /dev/null and b/static/assets/headers/header-back-custom.png differ
diff --git a/static/assets/headers/header-button.png b/static/assets/headers/header-button.png
new file mode 100644
index 00000000000..d1daf406f34
Binary files /dev/null and b/static/assets/headers/header-button.png differ
diff --git a/static/assets/headers/header-custom-title.png b/static/assets/headers/header-custom-title.png
new file mode 100644
index 00000000000..b2b1bbfdff0
Binary files /dev/null and b/static/assets/headers/header-custom-title.png differ
diff --git a/static/assets/headers/header-title.png b/static/assets/headers/header-title.png
new file mode 100644
index 00000000000..69b493cc97e
Binary files /dev/null and b/static/assets/headers/header-title.png differ
diff --git a/static/assets/headers/header-update-screen.mp4 b/static/assets/headers/header-update-screen.mp4
new file mode 100644
index 00000000000..24be186692e
Binary files /dev/null and b/static/assets/headers/header-update-screen.mp4 differ
diff --git a/static/assets/modal/modal.mp4 b/static/assets/modal/modal.mp4
new file mode 100644
index 00000000000..d5ed7d46466
Binary files /dev/null and b/static/assets/modal/modal.mp4 differ
diff --git a/static/assets/navigators/drawer/drawer-multiple.mp4 b/static/assets/navigators/drawer/drawer-multiple.mp4
new file mode 100644
index 00000000000..a6481747b5b
Binary files /dev/null and b/static/assets/navigators/drawer/drawer-multiple.mp4 differ
diff --git a/static/assets/navigators/drawer/drawer.mov b/static/assets/navigators/drawer/drawer.mov
deleted file mode 100755
index 7776f2081e1..00000000000
Binary files a/static/assets/navigators/drawer/drawer.mov and /dev/null differ
diff --git a/static/assets/navigators/drawer/drawer.mp4 b/static/assets/navigators/drawer/drawer.mp4
new file mode 100644
index 00000000000..86a7ce88864
Binary files /dev/null and b/static/assets/navigators/drawer/drawer.mp4 differ
diff --git a/static/assets/navigators/lifecycle-focus.mp4 b/static/assets/navigators/lifecycle-focus.mp4
new file mode 100644
index 00000000000..3654a75dc07
Binary files /dev/null and b/static/assets/navigators/lifecycle-focus.mp4 differ
diff --git a/static/assets/navigators/lifecycle.mp4 b/static/assets/navigators/lifecycle.mp4
new file mode 100644
index 00000000000..5ea76a7a63c
Binary files /dev/null and b/static/assets/navigators/lifecycle.mp4 differ
diff --git a/static/assets/navigators/params-to-parent.mp4 b/static/assets/navigators/params-to-parent.mp4
new file mode 100644
index 00000000000..d293b461cb0
Binary files /dev/null and b/static/assets/navigators/params-to-parent.mp4 differ
diff --git a/static/assets/navigators/passing-params.mp4 b/static/assets/navigators/passing-params.mp4
new file mode 100644
index 00000000000..dd90a99cf68
Binary files /dev/null and b/static/assets/navigators/passing-params.mp4 differ
diff --git a/static/assets/navigators/stack/back-home.mp4 b/static/assets/navigators/stack/back-home.mp4
new file mode 100644
index 00000000000..1d41c4503df
Binary files /dev/null and b/static/assets/navigators/stack/back-home.mp4 differ
diff --git a/static/assets/navigators/stack/basic_stack_nav.png b/static/assets/navigators/stack/basic_stack_nav.png
old mode 100755
new mode 100644
index bd11efec40a..bdc1fac5bed
Binary files a/static/assets/navigators/stack/basic_stack_nav.png and b/static/assets/navigators/stack/basic_stack_nav.png differ
diff --git a/static/assets/navigators/stack/pop-to-top.mp4 b/static/assets/navigators/stack/pop-to-top.mp4
new file mode 100644
index 00000000000..98efee4af53
Binary files /dev/null and b/static/assets/navigators/stack/pop-to-top.mp4 differ
diff --git a/static/assets/navigators/stack/simple-details.mp4 b/static/assets/navigators/stack/simple-details.mp4
new file mode 100644
index 00000000000..df6d42c4f1c
Binary files /dev/null and b/static/assets/navigators/stack/simple-details.mp4 differ
diff --git a/static/assets/navigators/stack/stack-push.mov b/static/assets/navigators/stack/stack-push.mov
deleted file mode 100755
index 524c58d212e..00000000000
Binary files a/static/assets/navigators/stack/stack-push.mov and /dev/null differ
diff --git a/static/assets/navigators/stack/stack-push.mp4 b/static/assets/navigators/stack/stack-push.mp4
new file mode 100644
index 00000000000..ad8561408c2
Binary files /dev/null and b/static/assets/navigators/stack/stack-push.mp4 differ
diff --git a/static/assets/navigators/stack/stack.mov b/static/assets/navigators/stack/stack.mov
deleted file mode 100755
index c1794be27fe..00000000000
Binary files a/static/assets/navigators/stack/stack.mov and /dev/null differ
diff --git a/static/assets/navigators/stack/stack.mp4 b/static/assets/navigators/stack/stack.mp4
new file mode 100644
index 00000000000..0d068e382e1
Binary files /dev/null and b/static/assets/navigators/stack/stack.mp4 differ
diff --git a/static/assets/navigators/tabs/bottom-tabs-demo.mov b/static/assets/navigators/tabs/bottom-tabs-demo.mov
deleted file mode 100755
index edc9651129e..00000000000
Binary files a/static/assets/navigators/tabs/bottom-tabs-demo.mov and /dev/null differ
diff --git a/static/assets/navigators/tabs/bottom-tabs-demo.mp4 b/static/assets/navigators/tabs/bottom-tabs-demo.mp4
new file mode 100644
index 00000000000..1dc48d6e17f
Binary files /dev/null and b/static/assets/navigators/tabs/bottom-tabs-demo.mp4 differ
diff --git a/static/assets/navigators/tabs/material-top-tabs.mov b/static/assets/navigators/tabs/material-top-tabs.mov
deleted file mode 100755
index 9df25117a98..00000000000
Binary files a/static/assets/navigators/tabs/material-top-tabs.mov and /dev/null differ
diff --git a/static/assets/navigators/tabs/material-top-tabs.mp4 b/static/assets/navigators/tabs/material-top-tabs.mp4
new file mode 100644
index 00000000000..237c59a88b7
Binary files /dev/null and b/static/assets/navigators/tabs/material-top-tabs.mp4 differ
diff --git a/static/assets/navigators/tabs/tabs-badges.png b/static/assets/navigators/tabs/tabs-badges.png
old mode 100755
new mode 100644
index c7774ac97b7..f2f3fbeb333
Binary files a/static/assets/navigators/tabs/tabs-badges.png and b/static/assets/navigators/tabs/tabs-badges.png differ
diff --git a/static/assets/navigators/tabs/tabs-minimal.png b/static/assets/navigators/tabs/tabs-minimal.png
new file mode 100644
index 00000000000..4195269c5ac
Binary files /dev/null and b/static/assets/navigators/tabs/tabs-minimal.png differ
diff --git a/static/assets/navigators/tabs/tabs-navigate.mp4 b/static/assets/navigators/tabs/tabs-navigate.mp4
new file mode 100644
index 00000000000..4e8cb65ae5f
Binary files /dev/null and b/static/assets/navigators/tabs/tabs-navigate.mp4 differ
diff --git a/static/assets/navigators/tabs/tabs-with-stack.mp4 b/static/assets/navigators/tabs/tabs-with-stack.mp4
new file mode 100644
index 00000000000..770a78d613e
Binary files /dev/null and b/static/assets/navigators/tabs/tabs-with-stack.mp4 differ
diff --git a/static/assets/statusbar/status-drawer-android.mp4 b/static/assets/statusbar/status-drawer-android.mp4
new file mode 100644
index 00000000000..35c6d2ae905
Binary files /dev/null and b/static/assets/statusbar/status-drawer-android.mp4 differ
diff --git a/static/assets/statusbar/status-drawer-ios.mp4 b/static/assets/statusbar/status-drawer-ios.mp4
new file mode 100644
index 00000000000..10ef8020380
Binary files /dev/null and b/static/assets/statusbar/status-drawer-ios.mp4 differ
diff --git a/static/assets/statusbar/status-stack-android.mp4 b/static/assets/statusbar/status-stack-android.mp4
new file mode 100644
index 00000000000..0e6bbae25fb
Binary files /dev/null and b/static/assets/statusbar/status-stack-android.mp4 differ
diff --git a/static/assets/statusbar/status-stack-ios.mp4 b/static/assets/statusbar/status-stack-ios.mp4
new file mode 100644
index 00000000000..f575ee930c4
Binary files /dev/null and b/static/assets/statusbar/status-stack-ios.mp4 differ
diff --git a/static/assets/statusbar/status-tab-android.mp4 b/static/assets/statusbar/status-tab-android.mp4
new file mode 100644
index 00000000000..23d65d44642
Binary files /dev/null and b/static/assets/statusbar/status-tab-android.mp4 differ
diff --git a/static/assets/statusbar/status-tab-ios.mp4 b/static/assets/statusbar/status-tab-ios.mp4
new file mode 100644
index 00000000000..4caeb8cf3ad
Binary files /dev/null and b/static/assets/statusbar/status-tab-ios.mp4 differ
diff --git a/static/css/code-block-buttons.css b/static/css/code-block-buttons.css
index e5bb9d22a61..8d689fc099e 100644
--- a/static/css/code-block-buttons.css
+++ b/static/css/code-block-buttons.css
@@ -13,7 +13,7 @@ pre .btnIcon {
color: #6b52ae;
background-color: transparent;
height: 30px;
- transition: all .25s ease-out;
+ transition: all 0.25s ease-out;
}
pre .btnIcon:hover {
@@ -27,7 +27,7 @@ pre .btnIcon:hover {
.btnIcon svg {
fill: currentColor;
- margin-right: .4em;
+ margin-right: 0.4em;
}
.btnIcon__label {
@@ -36,4 +36,4 @@ pre .btnIcon:hover {
.btnClipboard {
right: 10px;
-}
\ No newline at end of file
+}
diff --git a/static/examples/4.x/auth-flow.js b/static/examples/4.x/auth-flow.js
index 6a76b6b05ae..800f64a19e5 100755
--- a/static/examples/4.x/auth-flow.js
+++ b/static/examples/4.x/auth-flow.js
@@ -5,13 +5,12 @@ import {
StatusBar,
StyleSheet,
View,
- AsyncStorage
+ AsyncStorage,
} from 'react-native';
import { createSwitchNavigator, createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
-
class SignInScreen extends React.Component {
static navigationOptions = {
title: 'Please sign in',
@@ -39,7 +38,7 @@ class HomeScreen extends React.Component {
render() {
return (
-
+
);
@@ -112,13 +111,15 @@ const styles = StyleSheet.create({
const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
-export default createAppContainer(createSwitchNavigator(
- {
- AuthLoading: AuthLoadingScreen,
- App: AppStack,
- Auth: AuthStack,
- },
- {
- initialRouteName: 'AuthLoading',
- }
-));
+export default createAppContainer(
+ createSwitchNavigator(
+ {
+ AuthLoading: AuthLoadingScreen,
+ App: AppStack,
+ Auth: AuthStack,
+ },
+ {
+ initialRouteName: 'AuthLoading',
+ }
+ )
+);
diff --git a/static/examples/4.x/basic-header-config.js b/static/examples/4.x/basic-header-config.js
index d5809c0d2ec..fac2d788d4b 100755
--- a/static/examples/4.x/basic-header-config.js
+++ b/static/examples/4.x/basic-header-config.js
@@ -48,7 +48,8 @@ class DetailsScreen extends React.Component {
onPress={() =>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
),
headerRight: () => (
-
+
),
};
};
@@ -93,7 +97,8 @@ class DetailsScreen extends React.Component {
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
;
}
-}
\ No newline at end of file
+}
diff --git a/static/examples/4.x/hello-react-navigation.js b/static/examples/4.x/hello-react-navigation.js
index b658d064598..53872794481 100755
--- a/static/examples/4.x/hello-react-navigation.js
+++ b/static/examples/4.x/hello-react-navigation.js
@@ -19,4 +19,4 @@ const AppNavigator = createStackNavigator({
},
});
-export default createAppContainer(AppNavigator);
\ No newline at end of file
+export default createAppContainer(AppNavigator);
diff --git a/static/examples/4.x/multiple-navigate.js b/static/examples/4.x/multiple-navigate.js
index d16131753e0..f7d88ec23a0 100755
--- a/static/examples/4.x/multiple-navigate.js
+++ b/static/examples/4.x/multiple-navigate.js
@@ -47,4 +47,4 @@ export default class App extends React.Component {
render() {
return ;
}
-}
\ No newline at end of file
+}
diff --git a/static/examples/4.x/multiple-push.js b/static/examples/4.x/multiple-push.js
index 29d2bff5ac6..bd3107a1d1e 100755
--- a/static/examples/4.x/multiple-push.js
+++ b/static/examples/4.x/multiple-push.js
@@ -36,4 +36,4 @@ const RootStack = createStackNavigator({
Details: DetailsScreen,
});
-export default createAppContainer(RootStack);
\ No newline at end of file
+export default createAppContainer(RootStack);
diff --git a/static/examples/4.x/new-screen.js b/static/examples/4.x/new-screen.js
index 76b6240ccf3..a8f8a490b0d 100755
--- a/static/examples/4.x/new-screen.js
+++ b/static/examples/4.x/new-screen.js
@@ -43,4 +43,4 @@ export default class App extends React.Component {
render() {
return ;
}
-}
\ No newline at end of file
+}
diff --git a/static/examples/4.x/overriding-shared-styles.js b/static/examples/4.x/overriding-shared-styles.js
index dfe7217eb45..a996f0ad86b 100755
--- a/static/examples/4.x/overriding-shared-styles.js
+++ b/static/examples/4.x/overriding-shared-styles.js
@@ -46,7 +46,7 @@ class DetailsScreen extends React.Component {
render() {
/* 2. Get the param, provide a fallback value if not available */
const { navigation } = this.props;
- const itemId = navigation.getParam('itemId', 'NO-ID');
+ const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
return (
@@ -59,12 +59,14 @@ class DetailsScreen extends React.Component {
onPress={() =>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
- this.props.navigation.setParams({ otherParam: 'Updated!' })}
+ this.props.navigation.setParams({ otherParam: 'Updated!' })
+ }
/>
}>
+ }
+ >
diff --git a/static/examples/5.x/bottom-tab-prevent-default.js b/static/examples/5.x/bottom-tab-prevent-default.js
index a676e5a530c..d19e886b814 100755
--- a/static/examples/5.x/bottom-tab-prevent-default.js
+++ b/static/examples/5.x/bottom-tab-prevent-default.js
@@ -5,7 +5,7 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function HomeScreen({ navigation }) {
React.useEffect(() => {
- const unsubscribe = navigation.addListener('tabPress', e => {
+ const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
diff --git a/static/examples/5.x/custom-drawer-content.js b/static/examples/5.x/custom-drawer-content.js
index 718d0417850..4d3b651c99d 100755
--- a/static/examples/5.x/custom-drawer-content.js
+++ b/static/examples/5.x/custom-drawer-content.js
@@ -37,7 +37,9 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
- }>
+ }
+ >
diff --git a/static/examples/5.x/custom-header-title-component.js b/static/examples/5.x/custom-header-title-component.js
index 3e53d10afae..c3b7a5eb651 100755
--- a/static/examples/5.x/custom-header-title-component.js
+++ b/static/examples/5.x/custom-header-title-component.js
@@ -29,7 +29,7 @@ function App() {
}}
+ options={{ headerTitle: (props) => }}
/>
diff --git a/static/examples/5.x/custom-tab-bar.js b/static/examples/5.x/custom-tab-bar.js
index 7aae9fe48c3..b9b789f96a2 100755
--- a/static/examples/5.x/custom-tab-bar.js
+++ b/static/examples/5.x/custom-tab-bar.js
@@ -28,8 +28,8 @@ function MyTabBar({ state, descriptors, navigation }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
@@ -76,7 +76,7 @@ const Tab = createBottomTabNavigator();
export default function App() {
return (
- }>
+ }>
diff --git a/static/examples/5.x/drawer-actions.js b/static/examples/5.x/drawer-actions.js
index 5fac16204ab..2576b6812f8 100755
--- a/static/examples/5.x/drawer-actions.js
+++ b/static/examples/5.x/drawer-actions.js
@@ -60,7 +60,9 @@ const Drawer = createDrawerNavigator();
export default function App() {
return (
- }>
+ }
+ >
diff --git a/static/examples/5.x/drawer-dispatch.js b/static/examples/5.x/drawer-dispatch.js
index 27e862b2dea..09cf0bf2ab6 100755
--- a/static/examples/5.x/drawer-dispatch.js
+++ b/static/examples/5.x/drawer-dispatch.js
@@ -52,7 +52,9 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
- }>
+ }
+ >
diff --git a/static/examples/5.x/drawer-open-close-toggle.js b/static/examples/5.x/drawer-open-close-toggle.js
index 45232617220..f26b388c853 100755
--- a/static/examples/5.x/drawer-open-close-toggle.js
+++ b/static/examples/5.x/drawer-open-close-toggle.js
@@ -46,7 +46,9 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
- }>
+ }
+ >
diff --git a/static/examples/5.x/header-interaction.js b/static/examples/5.x/header-interaction.js
index 2b5dbaf6306..64d89051fbf 100755
--- a/static/examples/5.x/header-interaction.js
+++ b/static/examples/5.x/header-interaction.js
@@ -18,7 +18,7 @@ function HomeScreen({ navigation }) {
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
- setCount(c => c + 1)} title="Update count" />
+ setCount((c) => c + 1)} title="Update count" />
),
});
}, [navigation, setCount]);
@@ -36,7 +36,7 @@ function App() {
name="Home"
component={HomeScreen}
options={({ navigation, route }) => ({
- headerTitle: props => ,
+ headerTitle: (props) => ,
})}
/>
diff --git a/static/examples/5.x/hidden-components.js b/static/examples/5.x/hidden-components.js
index 5b07c3caafb..6f6eee0d346 100755
--- a/static/examples/5.x/hidden-components.js
+++ b/static/examples/5.x/hidden-components.js
@@ -23,10 +23,7 @@ export default function App() {
{() => (
- null}
- >
+ null}>
diff --git a/static/examples/5.x/material-bottom-tab-prevent-default.js b/static/examples/5.x/material-bottom-tab-prevent-default.js
index eada61ddc5c..451b2bc1b54 100755
--- a/static/examples/5.x/material-bottom-tab-prevent-default.js
+++ b/static/examples/5.x/material-bottom-tab-prevent-default.js
@@ -5,7 +5,7 @@ import { createMaterialBottomTabNavigator } from '@react-navigation/material-bot
function HomeScreen({ navigation }) {
React.useEffect(() => {
- const unsubscribe = navigation.addListener('tabPress', e => {
+ const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
diff --git a/static/examples/5.x/material-top-tab-custom-tab-bar.js b/static/examples/5.x/material-top-tab-custom-tab-bar.js
index 078a1368561..2d96312f8b7 100755
--- a/static/examples/5.x/material-top-tab-custom-tab-bar.js
+++ b/static/examples/5.x/material-top-tab-custom-tab-bar.js
@@ -13,8 +13,8 @@ function MyTabBar({ state, descriptors, navigation, position }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
@@ -39,7 +39,7 @@ function MyTabBar({ state, descriptors, navigation, position }) {
const inputRange = state.routes.map((_, i) => i);
const opacity = Animated.interpolate(position, {
inputRange,
- outputRange: inputRange.map(i => (i === index ? 1 : 0)),
+ outputRange: inputRange.map((i) => (i === index ? 1 : 0)),
});
return (
@@ -89,7 +89,7 @@ const Tab = createMaterialTopTabNavigator();
export default function App() {
return (
- }>
+ }>
diff --git a/static/examples/5.x/material-top-tab-prevent-default.js b/static/examples/5.x/material-top-tab-prevent-default.js
index 2307e4d4601..03dabeefc32 100755
--- a/static/examples/5.x/material-top-tab-prevent-default.js
+++ b/static/examples/5.x/material-top-tab-prevent-default.js
@@ -5,7 +5,7 @@ import { createMaterialTopTabNavigator } from '@react-navigation/material-top-ta
function HomeScreen({ navigation }) {
React.useEffect(() => {
- const unsubscribe = navigation.addListener('tabPress', e => {
+ const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
diff --git a/static/examples/5.x/navigate-set-options.js b/static/examples/5.x/navigate-set-options.js
index 95e2ffb03f0..6001ec61ab3 100755
--- a/static/examples/5.x/navigate-set-options.js
+++ b/static/examples/5.x/navigate-set-options.js
@@ -28,7 +28,7 @@ function ProfileScreen({ navigation, route }) {
onChangeText(text)}
+ onChangeText={(text) => onChangeText(text)}
value={value}
/>
navigation.goBack()} />
diff --git a/static/examples/5.x/redux-integration-nav-param.js b/static/examples/5.x/redux-integration-nav-param.js
index 24dc76b5ec1..1ba59aa5738 100755
--- a/static/examples/5.x/redux-integration-nav-param.js
+++ b/static/examples/5.x/redux-integration-nav-param.js
@@ -60,7 +60,7 @@ function StaticCounter({ route }) {
}
// Connect the screens to Redux
-let CounterContainer = connect(state => ({ count: state.count }))(Counter);
+let CounterContainer = connect((state) => ({ count: state.count }))(Counter);
// Create our stack navigator
let RootStack = createStackNavigator();
diff --git a/static/examples/5.x/redux-integration.js b/static/examples/5.x/redux-integration.js
index 81d848fcd8c..b1a14e1ea99 100755
--- a/static/examples/5.x/redux-integration.js
+++ b/static/examples/5.x/redux-integration.js
@@ -56,8 +56,8 @@ function StaticCounter({ count }) {
}
// Connect the screens to Redux
-let CounterContainer = connect(state => ({ count: state.count }))(Counter);
-let StaticCounterContainer = connect(state => ({ count: state.count }))(
+let CounterContainer = connect((state) => ({ count: state.count }))(Counter);
+let StaticCounterContainer = connect((state) => ({ count: state.count }))(
StaticCounter
);
diff --git a/static/examples/5.x/simple-focus-effect.js b/static/examples/5.x/simple-focus-effect.js
index 032c7feb11d..6e712968328 100755
--- a/static/examples/5.x/simple-focus-effect.js
+++ b/static/examples/5.x/simple-focus-effect.js
@@ -1,9 +1,6 @@
import * as React from 'react';
import { View } from 'react-native';
-import {
- NavigationContainer,
- useFocusEffect,
-} from '@react-navigation/native';
+import { NavigationContainer, useFocusEffect } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function ProfileScreen() {
diff --git a/static/examples/5.x/simple-header-button.js b/static/examples/5.x/simple-header-button.js
index 56bf259e89c..8ea58b3f33c 100755
--- a/static/examples/5.x/simple-header-button.js
+++ b/static/examples/5.x/simple-header-button.js
@@ -30,7 +30,7 @@ function App() {
name="Home"
component={HomeScreen}
options={{
- headerTitle: props => ,
+ headerTitle: (props) => ,
headerRight: () => (
alert('This is a button!')}
diff --git a/static/examples/5.x/simple-theme.js b/static/examples/5.x/simple-theme.js
index c95349da714..1058f30f694 100755
--- a/static/examples/5.x/simple-theme.js
+++ b/static/examples/5.x/simple-theme.js
@@ -1,9 +1,6 @@
import * as React from 'react';
import { Button, View, Text } from 'react-native';
-import {
- NavigationContainer,
- DefaultTheme,
-} from '@react-navigation/native';
+import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
diff --git a/static/examples/5.x/stack-actions.js b/static/examples/5.x/stack-actions.js
index d0323202a3a..fca2fcccb8a 100755
--- a/static/examples/5.x/stack-actions.js
+++ b/static/examples/5.x/stack-actions.js
@@ -1,7 +1,7 @@
-import * as React from 'react';
-import { View, Button, Text } from 'react-native';
import { NavigationContainer, StackActions } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
+import * as React from 'react';
+import { Button, Text, View } from 'react-native';
function HomeScreen({ navigation }) {
return (
@@ -31,11 +31,11 @@ function ProfileScreen({ navigation, route }) {
Profile!
{route.params.user}'s profile
navigation.dispatch(StackActions.pop(1))}
/>
navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }))
}
diff --git a/static/examples/5.x/status-bar.js b/static/examples/5.x/status-bar.js
index 26852dd9008..1605aafc3fe 100755
--- a/static/examples/5.x/status-bar.js
+++ b/static/examples/5.x/status-bar.js
@@ -9,7 +9,11 @@ function Screen1({ navigation }) {
Dark Screen
- navigation.navigate('Screen2')} color="#000" />
+ navigation.navigate('Screen2')}
+ color="#000"
+ />
);
}
@@ -19,7 +23,10 @@ function Screen2({ navigation }) {
Light Screen
- navigation.navigate('Screen1')} />
+ navigation.navigate('Screen1')}
+ />
);
}
diff --git a/static/examples/5.x/tab-based-navigation-badges.js b/static/examples/5.x/tab-based-navigation-badges.js
index e1eb559d540..910f9d05fc3 100755
--- a/static/examples/5.x/tab-based-navigation-badges.js
+++ b/static/examples/5.x/tab-based-navigation-badges.js
@@ -56,7 +56,11 @@ export default function App() {
inactiveTintColor: 'gray',
}}
>
-
+
diff --git a/static/examples/5.x/tab-based-navigation-icons.js b/static/examples/5.x/tab-based-navigation-icons.js
index 697c0afbdc4..a9fa0286106 100755
--- a/static/examples/5.x/tab-based-navigation-icons.js
+++ b/static/examples/5.x/tab-based-navigation-icons.js
@@ -33,7 +33,9 @@ export default function App() {
let iconName;
if (route.name === 'Home') {
- iconName = focused ? 'ios-information-circle' : 'ios-information-circle-outline';
+ iconName = focused
+ ? 'ios-information-circle'
+ : 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
diff --git a/static/examples/5.x/use-focus-effect.js b/static/examples/5.x/use-focus-effect.js
index edb8c10642a..6f9f722e2e3 100755
--- a/static/examples/5.x/use-focus-effect.js
+++ b/static/examples/5.x/use-focus-effect.js
@@ -1,9 +1,6 @@
import * as React from 'react';
import { Button, View, Text } from 'react-native';
-import {
- NavigationContainer,
- useFocusEffect,
-} from '@react-navigation/native';
+import { NavigationContainer, useFocusEffect } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
diff --git a/static/examples/5.x/use-is-focused.js b/static/examples/5.x/use-is-focused.js
index f28c5f50159..0934bd0bb72 100755
--- a/static/examples/5.x/use-is-focused.js
+++ b/static/examples/5.x/use-is-focused.js
@@ -1,9 +1,6 @@
import * as React from 'react';
import { View, Text } from 'react-native';
-import {
- NavigationContainer,
- useIsFocused,
-} from '@react-navigation/native';
+import { NavigationContainer, useIsFocused } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
function ProfileScreen() {
diff --git a/static/examples/5.x/use-navigation-state.js b/static/examples/5.x/use-navigation-state.js
index 21b86d7a618..9861846fa16 100755
--- a/static/examples/5.x/use-navigation-state.js
+++ b/static/examples/5.x/use-navigation-state.js
@@ -10,14 +10,14 @@ import { createStackNavigator } from '@react-navigation/stack';
function useIsFirstRouteInParent() {
const route = useRoute();
const isFirstRouteInParent = useNavigationState(
- state => state.routes[0].key === route.key
+ (state) => state.routes[0].key === route.key
);
return isFirstRouteInParent;
}
function usePreviousRouteName() {
- return useNavigationState(state =>
+ return useNavigationState((state) =>
state.routes[state.index - 1]?.name
? state.routes[state.index - 1].name
: 'None'
diff --git a/static/examples/5.x/use-safe-area.js b/static/examples/5.x/use-safe-area.js
index 3049eab1e8e..09a015b70ac 100755
--- a/static/examples/5.x/use-safe-area.js
+++ b/static/examples/5.x/use-safe-area.js
@@ -34,10 +34,7 @@ export default function App() {
{() => (
- null}
- >
+ null}>
diff --git a/static/examples/5.x/use-scroll-to-top.js b/static/examples/5.x/use-scroll-to-top.js
index c296fe4226c..a942e6ea496 100755
--- a/static/examples/5.x/use-scroll-to-top.js
+++ b/static/examples/5.x/use-scroll-to-top.js
@@ -1,9 +1,6 @@
import * as React from 'react';
import { View, ScrollView, Image } from 'react-native';
-import {
- NavigationContainer,
- useScrollToTop,
-} from '@react-navigation/native';
+import { NavigationContainer, useScrollToTop } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function Albums() {
diff --git a/static/examples/6.x/animated-drawer-content.js b/static/examples/6.x/animated-drawer-content.js
index 811a0adf35c..0a2bf175eca 100755
--- a/static/examples/6.x/animated-drawer-content.js
+++ b/static/examples/6.x/animated-drawer-content.js
@@ -49,7 +49,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
}
>
diff --git a/static/examples/6.x/custom-drawer-content.js b/static/examples/6.x/custom-drawer-content.js
index 642953deb41..4d3b651c99d 100755
--- a/static/examples/6.x/custom-drawer-content.js
+++ b/static/examples/6.x/custom-drawer-content.js
@@ -38,7 +38,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
}
>
diff --git a/static/examples/6.x/custom-tab-bar.js b/static/examples/6.x/custom-tab-bar.js
index 9201220e699..b9b789f96a2 100755
--- a/static/examples/6.x/custom-tab-bar.js
+++ b/static/examples/6.x/custom-tab-bar.js
@@ -28,8 +28,8 @@ function MyTabBar({ state, descriptors, navigation }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
diff --git a/static/examples/6.x/drawer-actions.js b/static/examples/6.x/drawer-actions.js
index e3d7df0db3b..2576b6812f8 100755
--- a/static/examples/6.x/drawer-actions.js
+++ b/static/examples/6.x/drawer-actions.js
@@ -61,7 +61,6 @@ export default function App() {
return (
}
>
diff --git a/static/examples/6.x/drawer-based-navigation.js b/static/examples/6.x/drawer-based-navigation.js
index 405c53788bb..967f5daa4ce 100755
--- a/static/examples/6.x/drawer-based-navigation.js
+++ b/static/examples/6.x/drawer-based-navigation.js
@@ -27,7 +27,7 @@ const Drawer = createDrawerNavigator();
export default function App() {
return (
-
+
diff --git a/static/examples/6.x/drawer-content-options.js b/static/examples/6.x/drawer-content-options.js
index 546a2c934ae..9a9b93a9934 100755
--- a/static/examples/6.x/drawer-content-options.js
+++ b/static/examples/6.x/drawer-content-options.js
@@ -24,7 +24,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
}
>
diff --git a/static/examples/6.x/drawer-example.js b/static/examples/6.x/drawer-example.js
index 8c7d33b22bd..8838ddf63ed 100755
--- a/static/examples/6.x/drawer-example.js
+++ b/static/examples/6.x/drawer-example.js
@@ -31,7 +31,7 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
-
+
}
>
diff --git a/static/examples/6.x/drawer-with-style.js b/static/examples/6.x/drawer-with-style.js
index 378f6826948..84ce30c4530 100755
--- a/static/examples/6.x/drawer-with-style.js
+++ b/static/examples/6.x/drawer-with-style.js
@@ -24,7 +24,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
({
headerTitle: (props) => ,
// Add a placeholder button without the `onPress` to avoid flicker
- headerRight: () => (
-
- ),
+ headerRight: () => ,
})}
/>
diff --git a/static/examples/6.x/hidden-components.js b/static/examples/6.x/hidden-components.js
index d9b3cbd2c94..baa2de5e7bf 100755
--- a/static/examples/6.x/hidden-components.js
+++ b/static/examples/6.x/hidden-components.js
@@ -25,16 +25,16 @@ export default function App() {
screenOptions={{ headerShown: false }}
>
- {() => (
- null}
- screenOptions={{ headerShown: false }}
- >
-
-
-
- )}
+ {() => (
+ null}
+ screenOptions={{ headerShown: false }}
+ >
+
+
+
+ )}
diff --git a/static/examples/6.x/material-top-tab-custom-tab-bar.js b/static/examples/6.x/material-top-tab-custom-tab-bar.js
index fee6d703c43..2d96312f8b7 100755
--- a/static/examples/6.x/material-top-tab-custom-tab-bar.js
+++ b/static/examples/6.x/material-top-tab-custom-tab-bar.js
@@ -13,8 +13,8 @@ function MyTabBar({ state, descriptors, navigation, position }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
diff --git a/static/examples/6.x/multiple-drawers-issue.js b/static/examples/6.x/multiple-drawers-issue.js
index 2bd954a1922..ff4d6d069d2 100644
--- a/static/examples/6.x/multiple-drawers-issue.js
+++ b/static/examples/6.x/multiple-drawers-issue.js
@@ -22,10 +22,7 @@ const LeftDrawer = createDrawerNavigator();
const LeftDrawerScreen = () => {
return (
-
+
);
@@ -36,7 +33,6 @@ const RightDrawer = createDrawerNavigator();
const RightDrawerScreen = () => {
return (
diff --git a/static/examples/6.x/multiple-drawers.js b/static/examples/6.x/multiple-drawers.js
index f42b98f08cb..f75c661effe 100755
--- a/static/examples/6.x/multiple-drawers.js
+++ b/static/examples/6.x/multiple-drawers.js
@@ -31,9 +31,9 @@ const LeftDrawer = createDrawerNavigator();
function LeftDrawerScreen() {
return (
+ screenOptions={{ drawerPosition: 'left' }}
+ >
);
@@ -44,13 +44,13 @@ const RightDrawer = createDrawerNavigator();
function RightDrawerScreen() {
return (
}
screenOptions={{
drawerPosition: 'right',
headerShown: false,
- }}>
+ }}
+ >
);
diff --git a/static/examples/6.x/navigation-context.js b/static/examples/6.x/navigation-context.js
index eb679cb31eb..51bc9048a9b 100755
--- a/static/examples/6.x/navigation-context.js
+++ b/static/examples/6.x/navigation-context.js
@@ -25,7 +25,6 @@ function SomeComponent() {
);
}
-
function ProfileScreen({ navigation }) {
return (
diff --git a/static/examples/6.x/nested-navigator-screen.js b/static/examples/6.x/nested-navigator-screen.js
index 7401e977a20..8d3b49a3f69 100644
--- a/static/examples/6.x/nested-navigator-screen.js
+++ b/static/examples/6.x/nested-navigator-screen.js
@@ -35,7 +35,7 @@ const Stack = createNativeStackNavigator();
function Root() {
return (
-
+
diff --git a/static/examples/6.x/no-nav-prop.js b/static/examples/6.x/no-nav-prop.js
index 11524e11df1..c3fec9bbfd6 100755
--- a/static/examples/6.x/no-nav-prop.js
+++ b/static/examples/6.x/no-nav-prop.js
@@ -1,9 +1,12 @@
import * as React from 'react';
import { View, Button, Text } from 'react-native';
-import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ createNavigationContainerRef,
+} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
-const navigationRef = createNavigationContainerRef()
+const navigationRef = createNavigationContainerRef();
function navigate(name, params) {
if (navigationRef.isReady()) {
diff --git a/static/examples/6.x/params-nested-navigators.js b/static/examples/6.x/params-nested-navigators.js
index dbb8959679b..d72be25303d 100755
--- a/static/examples/6.x/params-nested-navigators.js
+++ b/static/examples/6.x/params-nested-navigators.js
@@ -58,7 +58,7 @@ function Root() {
export default function App() {
return (
-
+
diff --git a/static/examples/6.x/simple-drawer.js b/static/examples/6.x/simple-drawer.js
index bd8fb3bf824..c288488bb1d 100755
--- a/static/examples/6.x/simple-drawer.js
+++ b/static/examples/6.x/simple-drawer.js
@@ -23,7 +23,7 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
-
+
diff --git a/static/examples/6.x/simple-theme.js b/static/examples/6.x/simple-theme.js
index a226fc63027..d24e24b0716 100755
--- a/static/examples/6.x/simple-theme.js
+++ b/static/examples/6.x/simple-theme.js
@@ -66,7 +66,7 @@ function Root() {
export default function App() {
return (
-
+
Profile!
{route.params.user}'s profile
navigation.dispatch(StackActions.pop(1))}
/>
navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }))
}
diff --git a/static/examples/6.x/status-bar-focus-effect.js b/static/examples/6.x/status-bar-focus-effect.js
index ab5eec3d1ea..3ebd4c2fce2 100755
--- a/static/examples/6.x/status-bar-focus-effect.js
+++ b/static/examples/6.x/status-bar-focus-effect.js
@@ -77,7 +77,7 @@ export default function App() {
return (
-
+
diff --git a/static/examples/6.x/system-themes.js b/static/examples/6.x/system-themes.js
index 5a5bbadb58d..1db4b3043ed 100755
--- a/static/examples/6.x/system-themes.js
+++ b/static/examples/6.x/system-themes.js
@@ -78,7 +78,7 @@ export default function App() {
return (
-
+
-
-
+
+
);
diff --git a/static/examples/7.x/animated-drawer-content.js b/static/examples/7.x/animated-drawer-content.js
index 811a0adf35c..0a2bf175eca 100755
--- a/static/examples/7.x/animated-drawer-content.js
+++ b/static/examples/7.x/animated-drawer-content.js
@@ -49,7 +49,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
}
>
diff --git a/static/examples/7.x/custom-drawer-content.js b/static/examples/7.x/custom-drawer-content.js
index 642953deb41..4d3b651c99d 100755
--- a/static/examples/7.x/custom-drawer-content.js
+++ b/static/examples/7.x/custom-drawer-content.js
@@ -38,7 +38,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
}
>
diff --git a/static/examples/7.x/custom-tab-bar.js b/static/examples/7.x/custom-tab-bar.js
index 9201220e699..b9b789f96a2 100755
--- a/static/examples/7.x/custom-tab-bar.js
+++ b/static/examples/7.x/custom-tab-bar.js
@@ -28,8 +28,8 @@ function MyTabBar({ state, descriptors, navigation }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
diff --git a/static/examples/7.x/drawer-actions.js b/static/examples/7.x/drawer-actions.js
index e3d7df0db3b..2576b6812f8 100755
--- a/static/examples/7.x/drawer-actions.js
+++ b/static/examples/7.x/drawer-actions.js
@@ -61,7 +61,6 @@ export default function App() {
return (
}
>
diff --git a/static/examples/7.x/drawer-based-navigation.js b/static/examples/7.x/drawer-based-navigation.js
deleted file mode 100755
index 405c53788bb..00000000000
--- a/static/examples/7.x/drawer-based-navigation.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as React from 'react';
-import { Button, View } from 'react-native';
-import { createDrawerNavigator } from '@react-navigation/drawer';
-import { NavigationContainer } from '@react-navigation/native';
-
-function HomeScreen({ navigation }) {
- return (
-
- navigation.navigate('Notifications')}
- title="Go to notifications"
- />
-
- );
-}
-
-function NotificationsScreen({ navigation }) {
- return (
-
- navigation.goBack()} title="Go back home" />
-
- );
-}
-
-const Drawer = createDrawerNavigator();
-
-export default function App() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/static/examples/7.x/drawer-content-options.js b/static/examples/7.x/drawer-content-options.js
index 546a2c934ae..9a9b93a9934 100755
--- a/static/examples/7.x/drawer-content-options.js
+++ b/static/examples/7.x/drawer-content-options.js
@@ -24,7 +24,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
}
>
diff --git a/static/examples/7.x/drawer-example.js b/static/examples/7.x/drawer-example.js
index 8c7d33b22bd..8838ddf63ed 100755
--- a/static/examples/7.x/drawer-example.js
+++ b/static/examples/7.x/drawer-example.js
@@ -31,7 +31,7 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
-
+
}
>
diff --git a/static/examples/7.x/drawer-with-style.js b/static/examples/7.x/drawer-with-style.js
index 378f6826948..84ce30c4530 100755
--- a/static/examples/7.x/drawer-with-style.js
+++ b/static/examples/7.x/drawer-with-style.js
@@ -24,7 +24,6 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
({
headerTitle: (props) => ,
// Add a placeholder button without the `onPress` to avoid flicker
- headerRight: () => (
-
- ),
+ headerRight: () => ,
})}
/>
diff --git a/static/examples/7.x/hidden-components.js b/static/examples/7.x/hidden-components.js
index d9b3cbd2c94..baa2de5e7bf 100755
--- a/static/examples/7.x/hidden-components.js
+++ b/static/examples/7.x/hidden-components.js
@@ -25,16 +25,16 @@ export default function App() {
screenOptions={{ headerShown: false }}
>
- {() => (
- null}
- screenOptions={{ headerShown: false }}
- >
-
-
-
- )}
+ {() => (
+ null}
+ screenOptions={{ headerShown: false }}
+ >
+
+
+
+ )}
diff --git a/static/examples/7.x/material-top-tab-custom-tab-bar.js b/static/examples/7.x/material-top-tab-custom-tab-bar.js
index fee6d703c43..2d96312f8b7 100755
--- a/static/examples/7.x/material-top-tab-custom-tab-bar.js
+++ b/static/examples/7.x/material-top-tab-custom-tab-bar.js
@@ -13,8 +13,8 @@ function MyTabBar({ state, descriptors, navigation, position }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
diff --git a/static/examples/7.x/multiple-drawers-issue.js b/static/examples/7.x/multiple-drawers-issue.js
index 2bd954a1922..ff4d6d069d2 100644
--- a/static/examples/7.x/multiple-drawers-issue.js
+++ b/static/examples/7.x/multiple-drawers-issue.js
@@ -22,10 +22,7 @@ const LeftDrawer = createDrawerNavigator();
const LeftDrawerScreen = () => {
return (
-
+
);
@@ -36,7 +33,6 @@ const RightDrawer = createDrawerNavigator();
const RightDrawerScreen = () => {
return (
diff --git a/static/examples/7.x/multiple-drawers.js b/static/examples/7.x/multiple-drawers.js
index f42b98f08cb..f75c661effe 100755
--- a/static/examples/7.x/multiple-drawers.js
+++ b/static/examples/7.x/multiple-drawers.js
@@ -31,9 +31,9 @@ const LeftDrawer = createDrawerNavigator();
function LeftDrawerScreen() {
return (
+ screenOptions={{ drawerPosition: 'left' }}
+ >
);
@@ -44,13 +44,13 @@ const RightDrawer = createDrawerNavigator();
function RightDrawerScreen() {
return (
}
screenOptions={{
drawerPosition: 'right',
headerShown: false,
- }}>
+ }}
+ >
);
diff --git a/static/examples/7.x/navigation-context.js b/static/examples/7.x/navigation-context.js
index eb679cb31eb..51bc9048a9b 100755
--- a/static/examples/7.x/navigation-context.js
+++ b/static/examples/7.x/navigation-context.js
@@ -25,7 +25,6 @@ function SomeComponent() {
);
}
-
function ProfileScreen({ navigation }) {
return (
diff --git a/static/examples/7.x/nested-navigator-screen.js b/static/examples/7.x/nested-navigator-screen.js
index 7401e977a20..8d3b49a3f69 100644
--- a/static/examples/7.x/nested-navigator-screen.js
+++ b/static/examples/7.x/nested-navigator-screen.js
@@ -35,7 +35,7 @@ const Stack = createNativeStackNavigator();
function Root() {
return (
-
+
diff --git a/static/examples/7.x/no-nav-prop.js b/static/examples/7.x/no-nav-prop.js
index 11524e11df1..c3fec9bbfd6 100755
--- a/static/examples/7.x/no-nav-prop.js
+++ b/static/examples/7.x/no-nav-prop.js
@@ -1,9 +1,12 @@
import * as React from 'react';
import { View, Button, Text } from 'react-native';
-import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ createNavigationContainerRef,
+} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
-const navigationRef = createNavigationContainerRef()
+const navigationRef = createNavigationContainerRef();
function navigate(name, params) {
if (navigationRef.isReady()) {
diff --git a/static/examples/7.x/params-nested-navigators.js b/static/examples/7.x/params-nested-navigators.js
index d2a20a7cad8..d04f5821133 100755
--- a/static/examples/7.x/params-nested-navigators.js
+++ b/static/examples/7.x/params-nested-navigators.js
@@ -64,7 +64,7 @@ function Root() {
export default function App() {
return (
-
+
diff --git a/static/examples/7.x/simple-drawer.js b/static/examples/7.x/simple-drawer.js
index bd8fb3bf824..c288488bb1d 100755
--- a/static/examples/7.x/simple-drawer.js
+++ b/static/examples/7.x/simple-drawer.js
@@ -23,7 +23,7 @@ const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
-
+
diff --git a/static/examples/7.x/simple-theme.js b/static/examples/7.x/simple-theme.js
index a226fc63027..d24e24b0716 100755
--- a/static/examples/7.x/simple-theme.js
+++ b/static/examples/7.x/simple-theme.js
@@ -66,7 +66,7 @@ function Root() {
export default function App() {
return (
-
+
Profile!
{route.params.user}'s profile
navigation.dispatch(StackActions.pop(1))}
/>
navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }))
}
diff --git a/static/examples/7.x/status-bar-focus-effect.js b/static/examples/7.x/status-bar-focus-effect.js
index ab5eec3d1ea..3ebd4c2fce2 100755
--- a/static/examples/7.x/status-bar-focus-effect.js
+++ b/static/examples/7.x/status-bar-focus-effect.js
@@ -77,7 +77,7 @@ export default function App() {
return (
-
+
diff --git a/static/examples/7.x/system-themes.js b/static/examples/7.x/system-themes.js
index 5a5bbadb58d..1db4b3043ed 100755
--- a/static/examples/7.x/system-themes.js
+++ b/static/examples/7.x/system-themes.js
@@ -78,7 +78,7 @@ export default function App() {
return (
-
+
-
-
+
+
);
diff --git a/static/img/spiro.svg b/static/img/spiro.svg
index a5c8c510ec8..5d9439ffec7 100644
--- a/static/img/spiro.svg
+++ b/static/img/spiro.svg
@@ -1 +1 @@
-Spiro Created with Sketch.
\ No newline at end of file
+Spiro Created with Sketch.
diff --git a/static/js/snack-helpers.js b/static/js/snack-helpers.js
index 801c8d40b60..66f7f19df11 100644
--- a/static/js/snack-helpers.js
+++ b/static/js/snack-helpers.js
@@ -155,9 +155,9 @@ function appendSnackLink() {
link.target = '_blank';
if (label) {
- link.innerHTML = `Try the "${label}" example on Snack ${openIcon}`;
+ link.innerHTML = `Try the "${label}" example on Snack ${openIcon}`;
} else {
- link.innerHTML = `Try this example on Snack ${openIcon}`;
+ link.innerHTML = `Try this example on Snack ${openIcon}`;
}
// Add the href and append the link element if we have some code
@@ -180,28 +180,15 @@ function appendSnackLink() {
}
// Don't try to add the link more than once!
- samp.remove()
- });
-}
-
-// This is used to update links like the following:
-// [Full source of what we have built so far](#example/full-screen-modal)
-function transformExistingSnackLinks() {
- document.querySelectorAll('a[href*="#example/"]').forEach((a) => {
- let urlParts = a.href.split('#example/');
- let templateId = urlParts[urlParts.length - 1];
- a.href = getSnackUrl({ templateId });
- a.target = '_blank';
+ samp.remove();
});
}
function initializeSnackObservers() {
appendSnackLink();
- transformExistingSnackLinks();
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(appendSnackLink);
- mutations.forEach(transformExistingSnackLinks);
});
mutationObserver.observe(document.documentElement, {
diff --git a/static/js/toc-fixes.js b/static/js/toc-fixes.js
new file mode 100644
index 00000000000..957c778ece2
--- /dev/null
+++ b/static/js/toc-fixes.js
@@ -0,0 +1,51 @@
+/**
+ * Docusaurus shows items in hidden tabs in the TOC.
+ * It's confusing since it doesn't represent the actual page.
+ * And clicking on those items doesn't do anything.
+ * This scripts syncs the TOCs with visible headings.
+ */
+const sync = () => {
+ const headings = document.querySelectorAll('article :is(h2, h3)');
+
+ // Get all visible headings
+ const titles = Array.from(headings)
+ .filter((el) => el.offsetParent)
+ .map((el) => trim(el.textContent));
+
+ const toc = document.querySelectorAll('.table-of-contents li > a');
+
+ // Hide TOC items that don't have a corresponding heading
+ toc.forEach((el) => {
+ if (!titles.includes(trim(el.textContent))) {
+ el.parentElement.style.display = 'none';
+ } else {
+ el.parentElement.style.display = 'block';
+ }
+ });
+};
+
+if (window.navigation) {
+ document.addEventListener('DOMContentLoaded', () => {
+ // For the first page load, wait till page is loaded
+ const observer = new MutationObserver(() => {
+ const article = document.querySelector('article');
+
+ if (article) {
+ observer.disconnect();
+ sync();
+
+ // Listen to navigation events to detect tab query param change
+ window.navigation.addEventListener('navigate', (event) => {
+ requestAnimationFrame(sync);
+ });
+ }
+ });
+
+ observer.observe(document.documentElement, {
+ childList: true,
+ subtree: true,
+ });
+ });
+}
+
+const trim = (str) => str.trim().replace(/[\u200B-\u200D\uFEFF]/g, '');
diff --git a/versioned_docs/version-1.x/auth-flow.md b/versioned_docs/version-1.x/auth-flow.md
index b2d628d60c6..7ce45b5ea07 100644
--- a/versioned_docs/version-1.x/auth-flow.md
+++ b/versioned_docs/version-1.x/auth-flow.md
@@ -6,10 +6,10 @@ sidebar_label: Authentication flows
Most apps require that a user authenticate in some way to have access to data associated with a user or other private content. Typically the flow will look like this:
-* The user opens the app.
-* The app loads some authentication state from persistent storage (for example, `AsyncStorage`).
-* When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
-* When the user signs out, we clear the authentication state and send them back to authentication screens.
+- The user opens the app.
+- The app loads some authentication state from persistent storage (for example, `AsyncStorage`).
+- When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
+- When the user signs out, we clear the authentication state and send them back to authentication screens.
> Note: we say "authentication screens" because usually there is more than one. You may have a main screen with a username and password field, another for "forgot password", and another set for sign up.
diff --git a/versioned_docs/version-1.x/connecting-navigation-prop.md b/versioned_docs/version-1.x/connecting-navigation-prop.md
index 7f24246a255..4dae362c806 100644
--- a/versioned_docs/version-1.x/connecting-navigation-prop.md
+++ b/versioned_docs/version-1.x/connecting-navigation-prop.md
@@ -14,7 +14,14 @@ export default class MyBackButton extends React.Component {
render() {
// This will throw an 'undefined is not a function' exception because the navigation
// prop is undefined.
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
```
@@ -30,7 +37,14 @@ import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
diff --git a/versioned_docs/version-1.x/custom-android-back-button-handling.md b/versioned_docs/version-1.x/custom-android-back-button-handling.md
index 9c12183d893..c5b77f3e93c 100644
--- a/versioned_docs/version-1.x/custom-android-back-button-handling.md
+++ b/versioned_docs/version-1.x/custom-android-back-button-handling.md
@@ -13,11 +13,17 @@ Returning `true` from `onBackButtonPressAndroid` denotes that we have handled th
```js
class ScreenWithCustomBackBehavior extends React.Component {
componentDidMount() {
- BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid);
+ BackHandler.addEventListener(
+ 'hardwareBackPress',
+ this.onBackButtonPressAndroid
+ );
}
componentWillUnmount() {
- BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid);
+ BackHandler.removeEventListener(
+ 'hardwareBackPress',
+ this.onBackButtonPressAndroid
+ );
}
onBackButtonPressAndroid = () => {
diff --git a/versioned_docs/version-1.x/custom-navigator-overview.md b/versioned_docs/version-1.x/custom-navigator-overview.md
index 914ec05c96d..6f1cd0dc6a7 100644
--- a/versioned_docs/version-1.x/custom-navigator-overview.md
+++ b/versioned_docs/version-1.x/custom-navigator-overview.md
@@ -37,13 +37,18 @@ const AppNavigator = StackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
someEvent() {
// call navigate for AppNavigator here:
- this.navigator && this.navigator.dispatch(
- NavigationActions.navigate({ routeName: someRouteName })
- );
+ this.navigator &&
+ this.navigator.dispatch(
+ NavigationActions.navigate({ routeName: someRouteName })
+ );
}
render() {
return (
- { this.navigator = nav; }} />
+ {
+ this.navigator = nav;
+ }}
+ />
);
}
}
diff --git a/versioned_docs/version-1.x/deep-linking.md b/versioned_docs/version-1.x/deep-linking.md
index 4e3b7e229aa..bbbffeb5ba2 100644
--- a/versioned_docs/version-1.x/deep-linking.md
+++ b/versioned_docs/version-1.x/deep-linking.md
@@ -4,7 +4,7 @@ title: Deep linking
sidebar_label: Deep linking
---
-In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `mychat://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
+In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `example://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
## Configuration
@@ -36,7 +36,7 @@ You need to specify a scheme for your app. You can register for a scheme in your
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -90,14 +90,14 @@ Next, let's configure our navigation container to extract the path from the app'
```js
const SimpleApp = StackNavigator({...}));
-const prefix = 'mychat://';
+const prefix = 'example://';
const MainApp = () => ;
```
### iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
@@ -116,7 +116,7 @@ In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
In Xcode, open the project at `SimpleApp/ios/SimpleApp.xcodeproj`. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
Now you can press play in Xcode, or re-build on the command line:
@@ -127,10 +127,10 @@ react-native run-ios
To test the URI on the simulator, run the following:
```
-xcrun simctl openurl booted mychat://chat/Eric
+xcrun simctl openurl booted example://chat/Eric
```
-To test the URI on a real device, open Safari and type `mychat://chat/Eric`.
+To test the URI on a real device, open Safari and type `example://chat/Eric`.
### Android
@@ -153,7 +153,7 @@ In `SimpleApp/android/app/src/main/AndroidManifest.xml`, do these followings adj
-
+
```
@@ -167,7 +167,7 @@ react-native run-android
To test the intent handling in Android, run the following:
```
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/Eric" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/Eric" com.simpleapp
```
## Disable deep linking
diff --git a/versioned_docs/version-1.x/drawer-based-navigation.md b/versioned_docs/version-1.x/drawer-based-navigation.md
index 8f1d5f44cda..78e06112a3d 100644
--- a/versioned_docs/version-1.x/drawer-based-navigation.md
+++ b/versioned_docs/version-1.x/drawer-based-navigation.md
@@ -10,7 +10,8 @@ class HomeScreen extends React.Component {
return (
this.props.navigation.navigate('DrawerOpen')}>
+ onPress={() => this.props.navigation.navigate('DrawerOpen')}
+ >
Open Drawer
Home
@@ -24,7 +25,8 @@ class SettingsScreen extends React.Component {
return (
this.props.navigation.navigate('DrawerOpen')}>
+ onPress={() => this.props.navigation.navigate('DrawerOpen')}
+ >
Open Drawer
Settings
diff --git a/versioned_docs/version-1.x/drawer-navigator.md b/versioned_docs/version-1.x/drawer-navigator.md
index 26688f99e3e..f61d0ddbd40 100644
--- a/versioned_docs/version-1.x/drawer-navigator.md
+++ b/versioned_docs/version-1.x/drawer-navigator.md
@@ -5,7 +5,7 @@ sidebar_label: DrawerNavigator
---
```js
-DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
+DrawerNavigator(RouteConfigs, DrawerNavigatorConfig);
```
### RouteConfigs
@@ -37,7 +37,10 @@ import { DrawerItems, SafeAreaView } from 'react-navigation';
const CustomDrawerContentComponent = (props) => (
-
+
@@ -102,15 +105,15 @@ The navigator component created by `DrawerNavigator(...)` takes the following pr
- `screenProps` - Pass down extra options to child screens, for example:
- ```jsx
- const DrawerNav = DrawerNavigator({
- // config
- });
+```jsx
+const DrawerNav = DrawerNavigator({
+ // config
+});
-
- ```
+
+```
### Nesting `DrawerNavigation`
diff --git a/versioned_docs/version-1.x/glossary-of-terms.md b/versioned_docs/version-1.x/glossary-of-terms.md
index 4bf82695b43..7c89dcc8ef6 100644
--- a/versioned_docs/version-1.x/glossary-of-terms.md
+++ b/versioned_docs/version-1.x/glossary-of-terms.md
@@ -18,7 +18,7 @@ A screen component is a component that we use in our route configuration.
const RootStack = StackNavigator(
{
Home: {
- screen: HomeScreen, // <----
+ screen: HomeScreen, // <----
},
Details: {
screen: DetailsScreen, // <----
@@ -32,7 +32,7 @@ const RootStack = StackNavigator(
The suffix `Screen` in the component name is entirely optional, but a frequently used convention; we could call it `CasaPantalla` and this would work just the same.
-We saw earlier that our screen components are provided with the `navigator` prop. It's important to note that *this only happens if the screen is rendered as a route by React Navigation* (for example, in response to `this.props.navigation.navigate`). For example, if we render `DetailsScreen` as a child of `HomeScreen`, then `DetailsScreen` won't be provided with the `navigation` prop, and when you press the "Go to Details... again" button on the Home screen, the app will throw one of the quintessential JavaScript exceptions "undefined is not an object".
+We saw earlier that our screen components are provided with the `navigator` prop. It's important to note that _this only happens if the screen is rendered as a route by React Navigation_ (for example, in response to `this.props.navigation.navigate`). For example, if we render `DetailsScreen` as a child of `HomeScreen`, then `DetailsScreen` won't be provided with the `navigation` prop, and when you press the "Go to Details... again" button on the Home screen, the app will throw one of the quintessential JavaScript exceptions "undefined is not an object".
```js
class HomeScreen extends React.Component {
diff --git a/versioned_docs/version-1.x/handling-iphonex.md b/versioned_docs/version-1.x/handling-iphonex.md
index c60fce16e23..3e35b9e464a 100644
--- a/versioned_docs/version-1.x/handling-iphonex.md
+++ b/versioned_docs/version-1.x/handling-iphonex.md
@@ -39,12 +39,8 @@ class App extends Component {
render() {
return (
-
- This is top text.
-
-
- This is bottom text.
-
+ This is top text.
+ This is bottom text.
);
}
diff --git a/versioned_docs/version-1.x/headers.md b/versioned_docs/version-1.x/headers.md
index a32bff7be47..1886d52af92 100644
--- a/versioned_docs/version-1.x/headers.md
+++ b/versioned_docs/version-1.x/headers.md
@@ -43,7 +43,7 @@ class DetailsScreen extends React.Component {
return {
title: params ? params.otherParam : 'A Nested Details Screen',
- }
+ };
};
/* render function, etc */
@@ -65,11 +65,11 @@ We only needed the `navigation` prop in the above example but you may in some ca
It's often necessary to update the `navigationOptions` configuration for the active screen from the mounted screen component itself. We can do this using `this.props.navigation.setParams`
```js
- /* Inside of render() */
- this.props.navigation.setParams({otherParam: 'Updated!'})}
- />
+/* Inside of render() */
+ this.props.navigation.setParams({ otherParam: 'Updated!' })}
+/>
```
→ Run this code
diff --git a/versioned_docs/version-1.x/hello-react-navigation.md b/versioned_docs/version-1.x/hello-react-navigation.md
index 61ae0ddd08d..0bce7ad13eb 100644
--- a/versioned_docs/version-1.x/hello-react-navigation.md
+++ b/versioned_docs/version-1.x/hello-react-navigation.md
@@ -6,7 +6,7 @@ sidebar_label: Hello React Navigation
In a web browser, you can link to different pages using an anchor (``) tag. When the user clicks on a link, the URL is pushed to the browser history stack. When the user presses the back button, the browser pops the item from the top of the history stack, so the active page is now the previously visited page. React Native doesn't have a built-in idea of a global history stack like a web browser does -- this is where React Navigation enters the story.
-React Navigation's `StackNavigator` provides a way for your app to transition between screens and manage navigation history. If your app uses only one `StackNavigator` then it is conceptually similar to how a web browser handles navigation state - your app pushes and pops items from the navigation stack as users interact with it, and this results in the user seeing different screens. A key difference between how this works in a web browser and in React Navigation is that React Navigation's `StackNavigator` provides the gestures and animations that you would expect on Android and iOS when navigating between routes in the stack.
+React Navigation's `StackNavigator` provides a way for your app to transition between screens and manage navigation history. If your app uses only one `StackNavigator` then it is conceptually similar to how a web browser handles navigation state - your app pushes and pops items from the navigation stack as users interact with it, and this results in the user seeing different screens. A key difference between how this works in a web browser and in React Navigation is that React Navigation's `StackNavigator` provides the gestures and animations that you would expect on Android and iOS when navigating between routes in the stack.
All we need to get started using React Navigation is a `StackNavigator`.
diff --git a/versioned_docs/version-1.x/navigating.md b/versioned_docs/version-1.x/navigating.md
index 9c63bd8dd86..c68283baa53 100644
--- a/versioned_docs/version-1.x/navigating.md
+++ b/versioned_docs/version-1.x/navigating.md
@@ -48,8 +48,8 @@ class HomeScreen extends React.Component {
Let's break down this down:
-* `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in `StackNavigator` (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
-* `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
+- `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in `StackNavigator` (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
+- `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
> If we call `this.props.navigation.navigate` with a route name that we haven't defined on a `StackNavigator`, nothing will happen. Said another way, we can only navigate to routes that have been defined on our `StackNavigator` — we cannot navigate to an arbitrary component.
@@ -113,7 +113,7 @@ Another common requirement is to be able to go back _multiple_ screens -- for ex
## Summary
-* `this.props.navigation.navigate('RouteName')` pushes a new route to the `StackNavigator`. We can call it as many times as we like and it will continue pushing routes.
-* The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
-* The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
-* [Full source of what we have built so far](https://snack.expo.io/@react-navigation/going-back).
+- `this.props.navigation.navigate('RouteName')` pushes a new route to the `StackNavigator`. We can call it as many times as we like and it will continue pushing routes.
+- The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
+- The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
+- [Full source of what we have built so far](https://snack.expo.io/@react-navigation/going-back).
diff --git a/versioned_docs/version-1.x/navigation-actions.md b/versioned_docs/version-1.x/navigation-actions.md
index c66f3cc24ab..361460ce185 100644
--- a/versioned_docs/version-1.x/navigation-actions.md
+++ b/versioned_docs/version-1.x/navigation-actions.md
@@ -10,18 +10,18 @@ Note that if you want to dispatch react-navigation actions you should use the ac
The following actions are supported:
-* [Navigate](#navigate) - Navigate to another route
-* [Back](#back) - Go back to previous state
-* [Set Params](#setparams) - Set Params for given route
-* [Init](#init) - Used to initialize first state if state is undefined
+- [Navigate](#navigate) - Navigate to another route
+- [Back](#back) - Go back to previous state
+- [Set Params](#setparams) - Set Params for given route
+- Init - Used to initialize first state if state is undefined
Within a stack, you can also use:
-* [Reset](#reset) - Replace current state with a new state
-* [Replace](#replace) - Replace a route at a given key with another route
-* [Push](#push) - Add a route on the top of the stack, and navigate forward to it
-* [Pop](#pop) - Navigate back to previous routes
-* [PopToTop](#poptotop) - Navigate to the top route of the stack, dismissing all other routes
+- [Reset](#reset) - Replace current state with a new state
+- [Replace](#replace) - Replace a route at a given key with another route
+- Push - Add a route on the top of the stack, and navigate forward to it
+- Pop - Navigate back to previous routes
+- PopToTop - Navigate to the top route of the stack, dismissing all other routes
The action creator functions define `toString()` to return the action type, which enables easy usage with third-party Redux libraries, including redux-actions and redux-saga.
@@ -29,10 +29,10 @@ The action creator functions define `toString()` to return the action type, whic
The `Navigate` action will update the current state with the result of a `Navigate` action.
-* `routeName` - _String_ - Required - A destination routeName that has been registered somewhere in the app's router
-* `params` - _Object_ - Optional - Params to merge into the destination route
-* `action` - _Object_ - Optional - (advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the actions described in this doc can be set as a sub-action.
-* `key` - _String_ - Optional - The identifier for the route to navigate to. Navigate back to this route if it already exists
+- `routeName` - _String_ - Required - A destination routeName that has been registered somewhere in the app's router
+- `params` - _Object_ - Optional - Params to merge into the destination route
+- `action` - _Object_ - Optional - (advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the actions described in this doc can be set as a sub-action.
+- `key` - _String_ - Optional - The identifier for the route to navigate to. Navigate back to this route if it already exists
```js
import { NavigationActions } from 'react-navigation';
@@ -52,9 +52,9 @@ this.props.navigation.dispatch(navigateAction);
The `Reset` action wipes the whole navigation state and replaces it with the result of several actions.
-* `index` - _number_ - required - Index of the active route on `routes` array in navigation `state`.
-* `actions` - _array_ - required - Array of Navigation Actions that will replace the navigation state.
-* `key` - _string or null_ - optional - If set, the navigator with the given key will reset. If null, the root navigator will reset.
+- `index` - _number_ - required - Index of the active route on `routes` array in navigation `state`.
+- `actions` - _array_ - required - Array of Navigation Actions that will replace the navigation state.
+- `key` - _string or null_ - optional - If set, the navigator with the given key will reset. If null, the root navigator will reset.
```js
import { NavigationActions } from 'react-navigation';
@@ -90,18 +90,18 @@ this.props.navigation.dispatch(resetAction);
The `Replace` action replaces the route at the given key with another route.
-* `key` - _string - required - Key of the route to replace.
-* `newKey` - _string - Key to use for the replacement route. Generated automatically if not provided.
-* `routeName` - _string - `routeName` to use for replacement route.
-* `params` - _object_ - Parameters to pass in to the replacement route.
-* `action` - _object_ - Optional sub-action.
-* `immediate`* - _boolean_ - _Currently has no effect_, this is a placeholder for when `StackNavigator` supports animated replace (it currently does not).
+- `key` - \_string - required - Key of the route to replace.
+- `newKey` - \_string - Key to use for the replacement route. Generated automatically if not provided.
+- `routeName` - \_string - `routeName` to use for replacement route.
+- `params` - _object_ - Parameters to pass in to the replacement route.
+- `action` - _object_ - Optional sub-action.
+- `immediate`\* - _boolean_ - _Currently has no effect_, this is a placeholder for when `StackNavigator` supports animated replace (it currently does not).
### Back
Go back to previous screen and close current screen. `back` action creator takes in one optional parameter:
-* `key` - _string or null_ - optional - If set, navigation will go back from the given key. If null, navigation will go back anywhere.
+- `key` - _string or null_ - optional - If set, navigation will go back from the given key. If null, navigation will go back anywhere.
```js
import { NavigationActions } from 'react-navigation';
@@ -116,8 +116,8 @@ this.props.navigation.dispatch(backAction);
When dispatching `SetParams`, the router will produce a new state that has changed the params of a particular route, as identified by the key
-* `params` - _object_ - required - New params to be merged into existing route params
-* `key` - _string_ - required - Route key that should get the new params
+- `params` - _object_ - required - New params to be merged into existing route params
+- `key` - _string_ - required - Route key that should get the new params
```js
import { NavigationActions } from 'react-navigation';
diff --git a/versioned_docs/version-1.x/navigation-options.md b/versioned_docs/version-1.x/navigation-options.md
index 42ff0c4de13..5cd2848c3cb 100644
--- a/versioned_docs/version-1.x/navigation-options.md
+++ b/versioned_docs/version-1.x/navigation-options.md
@@ -38,7 +38,7 @@ The screenProps are passed in at render-time. If this screen was hosted in a Sim
```js
```
@@ -84,7 +84,7 @@ const MyTabNavigator = TabNavigator({
});
```
-Note that you can still decide to **also** specify the `navigationOptions` on the screens at the leaf level - e.g. the `ProfileScreen` above. The `navigationOptions` from the screen will be merged key-by-key with the default options coming from the navigator. Whenever both the navigator and screen define the same option (e.g. `headerTintColor`), the screen wins. Therefore, you could change the tint color when `ProfileScreen` is active by doing the following:
+Note that you can still decide to **also** specify the `navigationOptions` on the screens at the leaf level - e.g. the `ProfileScreen` above. The `navigationOptions` from the screen will be merged key-by-key with the default options coming from the navigator. Whenever both the navigator and screen define the same option (e.g. `headerTintColor`), the screen wins. Therefore, you could change the tint color when `ProfileScreen` is active by doing the following:
```js
class ProfileScreen extends React.Component {
@@ -102,5 +102,5 @@ List of available navigation options depends on the `navigator` the screen is ad
Check available options for:
- [`drawer navigator`](drawer-navigator.md#screen-navigation-options)
-- [`stack navigator`](stack-navigator.md#screen-navigation-options)
-- [`tab navigator`](tab-navigator.md#screen-navigation-options)
+- [`stack navigator`](stack-navigator.md#navigationoptions-used-by-stacknavigator)
+- [`tab navigator`](tab-navigator.md#navigationoptions-used-by-tabnavigator)
diff --git a/versioned_docs/version-1.x/navigation-prop.md b/versioned_docs/version-1.x/navigation-prop.md
index b5d9651dedc..de67d4cecbd 100644
--- a/versioned_docs/version-1.x/navigation-prop.md
+++ b/versioned_docs/version-1.x/navigation-prop.md
@@ -6,25 +6,25 @@ sidebar_label: Navigation prop
Each `screen` component in your app is provided with the `navigation` prop automatically. It looks like this:
-* `this.props.navigation`
- * `navigate` - go to another screen, figures out the action it needs to take to do it
- * `goBack` - close active screen and move back in the stack
- * `addListener` - subscribe to updates to navigation lifecycle
- * `isFocused` - function that returns `true` if the screen is focused and `false` otherwise.
- * `state` - current state/routes
- * `setParams` - make changes to route's params
- * `getParam` - get a specific param with fallback
- * `dispatch` - send an action to router
+- `this.props.navigation`
+ - `navigate` - go to another screen, figures out the action it needs to take to do it
+ - `goBack` - close active screen and move back in the stack
+ - `addListener` - subscribe to updates to navigation lifecycle
+ - `isFocused` - function that returns `true` if the screen is focused and `false` otherwise.
+ - `state` - current state/routes
+ - `setParams` - make changes to route's params
+ - `getParam` - get a specific param with fallback
+ - `dispatch` - send an action to router
It's important to highlight the `navigation` prop is _not_ passed in to _all_ components; only `screen` components receive this prop automatically! React Navigation doesn't do anything magic here. For example, if you were to define a `MyBackButton` component and render it as a child of a screen component, you would not be able to access the `navigation` prop on it.
There are several additional functions on `this.props.navigation` that only if the current navigator is a `StackNavigator`. These functions are alternatives to `navigate` and `goBack` and you can use whichever you prefer. The functions are:
-* `this.props.navigation`
- * `push` - navigate forward to new route in stack
- * `pop` - go back in the stack
- * `popToTop` - go to the top of the stack
- * `replace` - replace the current route with a new one
+- `this.props.navigation`
+ - `push` - navigate forward to new route in stack
+ - `pop` - go back in the stack
+ - `popToTop` - go to the top of the stack
+ - `replace` - replace the current route with a new one
## Common API reference
@@ -38,10 +38,10 @@ Call this to link to another screen in your app. Takes the following arguments:
OR
`navigation.navigate(routeName, params, action)`
-* `routeName` - A destination routeName that has been registered somewhere in the app's router
-* `params` - Params to merge into the destination route
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions) for a full list of supported actions.
-* `key` - Optional identifier of what route to navigate to. Navigate **back** to this route, if it already exists
+- `routeName` - A destination routeName that has been registered somewhere in the app's router
+- `params` - Params to merge into the destination route
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions) for a full list of supported actions.
+- `key` - Optional identifier of what route to navigate to. Navigate **back** to this route, if it already exists
```js
class HomeScreen extends React.Component {
@@ -90,10 +90,10 @@ class HomeScreen extends React.Component {
Consider the following navigation stack history:
```javascript
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_A});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_B});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_C});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_D});
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_A });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_B });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_C });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_D });
```
Now you are on _screen D_ and want to go back to _screen A_ (popping D, C, and B).
@@ -107,17 +107,17 @@ navigation.goBack(SCREEN_KEY_B) // will go to screen A FROM screen B
React Navigation emits events to screen components that subscribe to them:
-* `willBlur` - the screen will be unfocused
-* `willFocus` - the screen will focus
-* `didFocus` - the screen focused (if there was a transition, the transition completed)
-* `didBlur` - the screen unfocused (if there was a transition, the transition completed)
+- `willBlur` - the screen will be unfocused
+- `willFocus` - the screen will focus
+- `didFocus` - the screen focused (if there was a transition, the transition completed)
+- `didBlur` - the screen unfocused (if there was a transition, the transition completed)
Example:
```javascript
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
- payload => {
+ (payload) => {
console.debug('didBlur', payload);
}
);
@@ -220,9 +220,9 @@ Similar to navigate, push will move you forward to a new route in the stack.
`navigation.push(routeName, params, action)`
-* `routeName` - A destination routeName that has been registered somewhere in the app's router
-* `params` - Params to merge into the destination route
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions) for a full list of supported actions.
+- `routeName` - A destination routeName that has been registered somewhere in the app's router
+- `params` - Params to merge into the destination route
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions) for a full list of supported actions.
### Pop
diff --git a/versioned_docs/version-1.x/redux-integration.md b/versioned_docs/version-1.x/redux-integration.md
index d7ec1205b7e..bb6fadee8ec 100644
--- a/versioned_docs/version-1.x/redux-integration.md
+++ b/versioned_docs/version-1.x/redux-integration.md
@@ -8,13 +8,13 @@ Some folks like to have their navigation state stored in the same place as the r
## Warning
-*You probably do not need to do this!* Storing your React Navigation state in your own Redux store is likely to give you a very difficult time if you don't know what you're doing. You lose out on some performance optimizations that React Navigation can do for you, for example. Please do not integrate your state into Redux without first ensuring that you can do what you need to do without it!
+_You probably do not need to do this!_ Storing your React Navigation state in your own Redux store is likely to give you a very difficult time if you don't know what you're doing. You lose out on some performance optimizations that React Navigation can do for you, for example. Please do not integrate your state into Redux without first ensuring that you can do what you need to do without it!
## Overview
1. To handle your app's navigation state in Redux, you can pass your own `navigation` prop to a navigator.
-2. Once you pass your own navigation prop to the navigator, the default [`navigation`](navigation-prop.md) prop gets destroyed. You must construct your own `navigation` prop with [`state`](navigation-prop.md#state-the-screen-s-current-state-route), [`dispatch`](navigation-prop.md#dispatch-send-an-action-to-the-router), and `addListener` properties.
+2. Once you pass your own navigation prop to the navigator, the default [`navigation`](navigation-prop.md) prop gets destroyed. You must construct your own `navigation` prop with [`state`](navigation-prop.md#state---the-screens-current-stateroute), [`dispatch`](navigation-prop.md#dispatch---send-an-action-to-the-router), and `addListener` properties.
3. The `state` will be fed from the reducer assigned to handle navigation state and the `dispatch` will be Redux's default `dispatch`. Thus you will be able to dispatch normal redux actions using `this.props.navigation.dispatch(ACTION)`, reducer will update the navigation state on the basis of dispatched action, the new navigation state will then be passed to the navigator.
@@ -142,23 +142,21 @@ To make jest tests work with your react-navigation app, you need to change the j
By using the following snippet, your nav component will be aware of the back button press actions and will correctly interact with your stack. This is really useful on Android.
```es6
-import React from "react";
-import { BackHandler } from "react-native";
-import { addNavigationHelpers, NavigationActions } from "react-navigation";
-
-const AppNavigation = TabNavigator(
- {
- Home: { screen: HomeScreen },
- Settings: { screen: SettingScreen }
- }
-);
+import React from 'react';
+import { BackHandler } from 'react-native';
+import { addNavigationHelpers, NavigationActions } from 'react-navigation';
+
+const AppNavigation = TabNavigator({
+ Home: { screen: HomeScreen },
+ Settings: { screen: SettingScreen },
+});
class ReduxNavigation extends React.Component {
componentDidMount() {
- BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
+ BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
componentWillUnmount() {
- BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
+ BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress = () => {
const { dispatch, nav } = this.props;
diff --git a/versioned_docs/version-1.x/routers.md b/versioned_docs/version-1.x/routers.md
index 382258ee0de..a01da861acc 100644
--- a/versioned_docs/version-1.x/routers.md
+++ b/versioned_docs/version-1.x/routers.md
@@ -35,12 +35,15 @@ See the [Custom Router API spec](custom-routers.md) to learn about the API of `S
To override navigation behavior, you can override the navigation state logic in `getStateForAction`, and manually manipulate the `routes` and `index`.
```js
-const MyApp = StackNavigator({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
+const MyApp = StackNavigator(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
const defaultGetStateForAction = MyApp.router.getStateForAction;
@@ -48,8 +51,8 @@ MyApp.router.getStateForAction = (action, state) => {
if (state && action.type === 'PushTwoProfiles') {
const routes = [
...state.routes,
- {key: 'A', routeName: 'Profile', params: { name: action.name1 }},
- {key: 'B', routeName: 'Profile', params: { name: action.name2 }},
+ { key: 'A', routeName: 'Profile', params: { name: action.name1 } },
+ { key: 'B', routeName: 'Profile', params: { name: action.name2 } },
];
return {
...state,
@@ -66,14 +69,17 @@ MyApp.router.getStateForAction = (action, state) => {
Sometimes you may want to prevent some navigation activity, depending on your route.
```js
-import { NavigationActions } from 'react-navigation'
+import { NavigationActions } from 'react-navigation';
-const MyStackRouter = StackRouter({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
+const MyStackRouter = StackRouter(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
const defaultGetStateForAction = MyStackRouter.router.getStateForAction;
@@ -97,22 +103,23 @@ MyStackRouter.router.getStateForAction = (action, state) => {
Perhaps your app has a unique URI which the built-in routers cannot handle. You can always extend the router `getActionForPathAndParams`.
```js
-import { NavigationActions } from 'react-navigation'
+import { NavigationActions } from 'react-navigation';
-const MyApp = StackNavigator({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
-const previousGetActionForPathAndParams = MyApp.router.getActionForPathAndParams;
+const MyApp = StackNavigator(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
+const previousGetActionForPathAndParams =
+ MyApp.router.getActionForPathAndParams;
Object.assign(MyApp.router, {
getActionForPathAndParams(path, params) {
- if (
- path === 'my/custom/path' &&
- params.magic === 'yes'
- ) {
+ if (path === 'my/custom/path' && params.magic === 'yes') {
// returns a profile navigate action for /my/custom/path?magic=yes
return NavigationActions.navigate({
routeName: 'Profile',
diff --git a/versioned_docs/version-1.x/screen-tracking.md b/versioned_docs/version-1.x/screen-tracking.md
index f4aa7a0dc81..1ce0ed422b6 100644
--- a/versioned_docs/version-1.x/screen-tracking.md
+++ b/versioned_docs/version-1.x/screen-tracking.md
@@ -55,24 +55,27 @@ import { GoogleAnalyticsTracker } from 'react-native-google-analytics-bridge';
const tracker = new GoogleAnalyticsTracker(GA_TRACKING_ID);
-const screenTracking = ({ getState }) => next => (action) => {
- if (
- action.type !== NavigationActions.NAVIGATE
- && action.type !== NavigationActions.BACK
- ) {
- return next(action);
- }
-
- const currentScreen = getCurrentRouteName(getState().navigation);
- const result = next(action);
- const nextScreen = getCurrentRouteName(getState().navigation);
- if (nextScreen !== currentScreen) {
- // the line below uses the Google Analytics tracker
- // change the tracker here to use other Mobile analytics SDK.
- tracker.trackScreenView(nextScreen);
- }
- return result;
-};
+const screenTracking =
+ ({ getState }) =>
+ (next) =>
+ (action) => {
+ if (
+ action.type !== NavigationActions.NAVIGATE &&
+ action.type !== NavigationActions.BACK
+ ) {
+ return next(action);
+ }
+
+ const currentScreen = getCurrentRouteName(getState().navigation);
+ const result = next(action);
+ const nextScreen = getCurrentRouteName(getState().navigation);
+ if (nextScreen !== currentScreen) {
+ // the line below uses the Google Analytics tracker
+ // change the tracker here to use other Mobile analytics SDK.
+ tracker.trackScreenView(nextScreen);
+ }
+ return result;
+ };
export default screenTracking;
```
diff --git a/versioned_docs/version-1.x/set-params-on-back.md b/versioned_docs/version-1.x/set-params-on-back.md
index b856b09d917..65bef243c3c 100644
--- a/versioned_docs/version-1.x/set-params-on-back.md
+++ b/versioned_docs/version-1.x/set-params-on-back.md
@@ -3,4 +3,3 @@ id: set-params-on-back
title: Update params when navigating back
sidebar_label: Update params when navigating back
---
-
diff --git a/versioned_docs/version-1.x/stack-navigator.md b/versioned_docs/version-1.x/stack-navigator.md
index 97f4e247766..9246d3bcc47 100644
--- a/versioned_docs/version-1.x/stack-navigator.md
+++ b/versioned_docs/version-1.x/stack-navigator.md
@@ -44,30 +44,30 @@ StackNavigator({
Options for the router:
-* `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
-* `initialRouteParams` - The params for the initial route
-* `navigationOptions` - Default navigation options to use for screens
-* `paths` - A mapping of overrides for the paths set in the route configs
+- `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
+- `initialRouteParams` - The params for the initial route
+- `navigationOptions` - Default navigation options to use for screens
+- `paths` - A mapping of overrides for the paths set in the route configs
Visual options:
-* `mode` - Defines the style for rendering and transitions:
- * `card` - Use the standard iOS and Android screen transitions. This is the default.
- * `modal` - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
-* `headerMode` - Specifies how the header should be rendered:
- * `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
- * `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
- * `none` - No header will be rendered.
-* `headerTransitionPreset` - Specifies how the header should transition from one screen to another when `headerMode: float` is enabled.
- * `fade-in-place` - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
- * `uikit` - An approximation of the default behavior for iOS.
-* `cardStyle` - Use this prop to override or extend the default style for an individual card in stack.
-* `transitionConfig` - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](https://github.com/react-navigation/react-navigation/blob/1.x/flow/react-navigation.js)). Provided function will be passed the following arguments:
- * `transitionProps` - Transition props for the new screen.
- * `prevTransitionProps` - Transitions props for the old screen.
- * `isModal` - Boolean specifying if screen is modal.
-* `onTransitionStart` - Function to be invoked when the card transition animation is about to start.
-* `onTransitionEnd` - Function to be invoked once the card transition animation completes.
+- `mode` - Defines the style for rendering and transitions:
+ - `card` - Use the standard iOS and Android screen transitions. This is the default.
+ - `modal` - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
+- `headerMode` - Specifies how the header should be rendered:
+ - `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
+ - `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
+ - `none` - No header will be rendered.
+- `headerTransitionPreset` - Specifies how the header should transition from one screen to another when `headerMode: float` is enabled.
+ - `fade-in-place` - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
+ - `uikit` - An approximation of the default behavior for iOS.
+- `cardStyle` - Use this prop to override or extend the default style for an individual card in stack.
+- `transitionConfig` - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](https://github.com/react-navigation/react-navigation/blob/1.x/flow/react-navigation.js)). Provided function will be passed the following arguments:
+ - `transitionProps` - Transition props for the new screen.
+ - `prevTransitionProps` - Transitions props for the old screen.
+ - `isModal` - Boolean specifying if screen is modal.
+- `onTransitionStart` - Function to be invoked when the card transition animation is about to start.
+- `onTransitionEnd` - Function to be invoked once the card transition animation completes.
### `navigationOptions` used by `StackNavigator`
@@ -148,8 +148,8 @@ Whether you can use gestures to dismiss this screen. Defaults to true on iOS, fa
Object to override the distance of touch start from the edge of the screen to recognize gestures. It takes the following properties:
-* `horizontal` - _number_ - Distance for horizontal direction. Defaults to 25.
-* `vertical` - _number_ - Distance for vertical direction. Defaults to 135.
+- `horizontal` - _number_ - Distance for horizontal direction. Defaults to 25.
+- `vertical` - _number_ - Distance for vertical direction. Defaults to 135.
#### `gestureDirection`
@@ -159,7 +159,7 @@ String to override the direction for dismiss gesture. `default` for normal behav
The navigator component created by `StackNavigator(...)` takes the following props:
-* `screenProps` - Pass down extra options to child screens, for example:
+- `screenProps` - Pass down extra options to child screens, for example:
```js
const SomeStack = StackNavigator({
@@ -197,7 +197,7 @@ const ModalNavigator = StackNavigator(
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
- screenInterpolator: sceneProps => {
+ screenInterpolator: (sceneProps) => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
@@ -225,14 +225,14 @@ Header transitions can also be configured using `headerLeftInterpolator`, `heade
The navigator component created by `StackNavigator(...)` takes the following props:
-* `screenProps` - Pass down extra options to child screens and navigation options, for example:
+- `screenProps` - Pass down extra options to child screens and navigation options, for example:
- ```js
- const StackNav = StackNavigator({
- // config
- });
+```js
+const StackNav = StackNavigator({
+ // config
+});
-
- ```
+
+```
diff --git a/versioned_docs/version-1.x/status-bar.md b/versioned_docs/version-1.x/status-bar.md
index 86925728b9f..afb660e24e8 100644
--- a/versioned_docs/version-1.x/status-bar.md
+++ b/versioned_docs/version-1.x/status-bar.md
@@ -15,17 +15,12 @@ class Screen1 extends React.Component {
render() {
return (
-
-
- Light Screen
-
+
+ Light Screen
this.props.navigation.navigate('Screen2')}
- color={isAndroid ? "blue" : "#fff"}
+ color={isAndroid ? 'blue' : '#fff'}
/>
);
@@ -36,13 +31,8 @@ class Screen2 extends React.Component {
render() {
return (
-
-
- Dark Screen
-
+
+ Dark Screen
this.props.navigation.navigate('Screen1')}
@@ -54,16 +44,19 @@ class Screen2 extends React.Component {
```
```javascript
-export default StackNavigator({
- Screen1: {
- screen: Screen1,
+export default StackNavigator(
+ {
+ Screen1: {
+ screen: Screen1,
+ },
+ Screen2: {
+ screen: Screen2,
+ },
},
- Screen2: {
- screen: Screen2,
- },
-}, {
- headerMode: 'none',
-});
+ {
+ headerMode: 'none',
+ }
+);
```

@@ -97,9 +90,7 @@ class Screen2 extends React.Component {
render() {
return (
-
- Dark Screen
-
+ Dark Screen
this.props.navigation.navigate('Screen1')}
diff --git a/versioned_docs/version-1.x/switch-navigator.md b/versioned_docs/version-1.x/switch-navigator.md
index f0b336329ac..359d10bb043 100644
--- a/versioned_docs/version-1.x/switch-navigator.md
+++ b/versioned_docs/version-1.x/switch-navigator.md
@@ -5,7 +5,7 @@ sidebar_label: SwitchNavigator
---
```js
-SwitchNavigator(RouteConfigs, SwitchNavigatorConfig)
+SwitchNavigator(RouteConfigs, SwitchNavigatorConfig);
```
## RouteConfigs
diff --git a/versioned_docs/version-1.x/tab-based-navigation.md b/versioned_docs/version-1.x/tab-based-navigation.md
index 307be8785cb..05f0ed93bc5 100644
--- a/versioned_docs/version-1.x/tab-based-navigation.md
+++ b/versioned_docs/version-1.x/tab-based-navigation.md
@@ -88,10 +88,10 @@ export default TabNavigator(
Let's dissect this:
-* `tabBarIcon` is a property on `navigationOptions`, so we know we can use it on our screen components, but in this case chose to put it in the `TabNavigator` configuration in order to centralize the icon configuration for convenience.
-* `tabBarIcon` is a function that is given the `focused` state and `tintColor`. If you take a peek further down in the configuration you will see `tabBarOptions` and `activeTintColor` and `inactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `tintColor` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active).
-* In order to make the behavior the same on iOS and Android, we have explicitly provided `tabBarComponent`, `tabBarPosition`, `animationEnabled`, and `swipeEnabled`. The default behavior of `TabNavigator` is to show a tab bar on the top of the screen on Android and on the bottom on iOS, but here we force it to be on the bottom on both platforms.
-* Read the [full API reference](tab-navigator.md) for further information on `TabNavigator` configuration options.
+- `tabBarIcon` is a property on `navigationOptions`, so we know we can use it on our screen components, but in this case chose to put it in the `TabNavigator` configuration in order to centralize the icon configuration for convenience.
+- `tabBarIcon` is a function that is given the `focused` state and `tintColor`. If you take a peek further down in the configuration you will see `tabBarOptions` and `activeTintColor` and `inactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `tintColor` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active).
+- In order to make the behavior the same on iOS and Android, we have explicitly provided `tabBarComponent`, `tabBarPosition`, `animationEnabled`, and `swipeEnabled`. The default behavior of `TabNavigator` is to show a tab bar on the top of the screen on Android and on the bottom on iOS, but here we force it to be on the bottom on both platforms.
+- Read the [full API reference](tab-navigator.md) for further information on `TabNavigator` configuration options.
## Jumping between tabs
@@ -152,7 +152,7 @@ class HomeScreen extends React.Component {
render() {
return (
- { /* other code from before here */ }
+ {/* other code from before here */}
this.props.navigation.navigate('Details')}
@@ -166,7 +166,7 @@ class SettingsScreen extends React.Component {
render() {
return (
- { /* other code from before here */ }
+ {/* other code from before here */}
this.props.navigation.navigate('Details')}
diff --git a/versioned_docs/version-1.x/tab-navigator.md b/versioned_docs/version-1.x/tab-navigator.md
index 4a3b8298484..24ab6fb1f7c 100644
--- a/versioned_docs/version-1.x/tab-navigator.md
+++ b/versioned_docs/version-1.x/tab-navigator.md
@@ -5,7 +5,7 @@ sidebar_label: TabNavigator
---
```js
-TabNavigator(RouteConfigs, TabNavigatorConfig)
+TabNavigator(RouteConfigs, TabNavigatorConfig);
```
## RouteConfigs
@@ -15,8 +15,8 @@ The route configs object is a mapping from route name to a route config, which t
## TabNavigatorConfig
- `tabBarComponent` - Component to use as the tab bar, e.g. `TabBarBottom`
-(this is the default on iOS), `TabBarTop`
-(this is the default on Android).
+ (this is the default on iOS), `TabBarTop`
+ (this is the default on Android).
- `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`.
- `swipeEnabled` - Whether to allow swiping between tabs.
- `animationEnabled` - Whether to animate when changing tabs.
@@ -84,7 +84,7 @@ tabBarOptions: {
fontSize: 12,
},
tabStyle: {
- width: 100,
+ width: 100,
},
style: {
backgroundColor: 'blue',
@@ -132,12 +132,12 @@ The navigator component created by `TabNavigator(...)` takes the following props
- `screenProps` - Pass down extra options to child screens and navigation options, for example:
- ```js
- const TabNav = TabNavigator({
- // config
- });
+```js
+const TabNav = TabNavigator({
+ // config
+});
-
- ```
+
+```
diff --git a/versioned_docs/version-1.x/with-navigation-focus.md b/versioned_docs/version-1.x/with-navigation-focus.md
index 0a6e0e78717..ebdb127ddcc 100644
--- a/versioned_docs/version-1.x/with-navigation-focus.md
+++ b/versioned_docs/version-1.x/with-navigation-focus.md
@@ -6,7 +6,7 @@ sidebar_label: withNavigationFocus
`withNavigationFocus` is a higher order component which passes the `isFocused` prop into a wrapped component. It's useful if you need to use the focus state in the render function of your screen component or another component rendered somewhere inside of a screen.
-* `withNavigationFocus(Component)` returns a component.
+- `withNavigationFocus(Component)` returns a component.
## Example
diff --git a/versioned_docs/version-2.x/app-containers.md b/versioned_docs/version-2.x/app-containers.md
index 5fe4d7e6265..6710ea80f2e 100644
--- a/versioned_docs/version-2.x/app-containers.md
+++ b/versioned_docs/version-2.x/app-containers.md
@@ -58,7 +58,7 @@ class App extends React.Component {
render() {
return (
{
+ ref={(nav) => {
this.navigator = nav;
}}
/>
diff --git a/versioned_docs/version-2.x/auth-flow.md b/versioned_docs/version-2.x/auth-flow.md
index 43604ed32e4..7793db03428 100644
--- a/versioned_docs/version-2.x/auth-flow.md
+++ b/versioned_docs/version-2.x/auth-flow.md
@@ -6,10 +6,10 @@ sidebar_label: Authentication flows
Most apps require that a user authenticate in some way to have access to data associated with a user or other private content. Typically the flow will look like this:
-* The user opens the app.
-* The app loads some authentication state from persistent storage (for example, `AsyncStorage`).
-* When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
-* When the user signs out, we clear the authentication state and send them back to authentication screens.
+- The user opens the app.
+- The app loads some authentication state from persistent storage (for example, `AsyncStorage`).
+- When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
+- When the user signs out, we clear the authentication state and send them back to authentication screens.
> Note: we say "authentication screens" because usually there is more than one. You may have a main screen with a username and password field, another for "forgot password", and another set for sign up.
diff --git a/versioned_docs/version-2.x/bottom-tab-navigator.md b/versioned_docs/version-2.x/bottom-tab-navigator.md
index 51ae60e6fd0..69f62e0601a 100644
--- a/versioned_docs/version-2.x/bottom-tab-navigator.md
+++ b/versioned_docs/version-2.x/bottom-tab-navigator.md
@@ -16,24 +16,24 @@ The route configs object is a mapping from route name to a route config, which t
## BottomTabNavigatorConfig
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
-* `tabBarComponent` - Optional, override component to use as the tab bar.
-* `tabBarOptions` - An object with the following properties:
- * `activeTintColor` - Label and icon color of the active tab.
- * `activeBackgroundColor` - Background color of the active tab.
- * `inactiveTintColor` - Label and icon color of the inactive tab.
- * `inactiveBackgroundColor` - Background color of the inactive tab.
- * `showLabel` - Whether to show label for tab, default is true.
- * `showIcon` - Whether to show icon for tab, default is true.
- * `style` - Style object for the tab bar.
- * `labelStyle` - Style object for the tab label.
- * `tabStyle` - Style object for the tab.
- * `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
- * `adaptive` - Should the tab icons and labels alignment change based on screen size? Defaults to `true` for iOS 11. If `false`, tab icons and labels align vertically all the time. When `true`, tab icons and labels align horizontally on tablet.
- * `safeAreaInset` - Override the `forceInset` prop for ``. Defaults to `{ bottom: 'always', top: 'never' }`. Available keys are `top | bottom | left | right` provided with the values `'always' | 'never'`.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
+- `tabBarComponent` - Optional, override component to use as the tab bar.
+- `tabBarOptions` - An object with the following properties:
+ - `activeTintColor` - Label and icon color of the active tab.
+ - `activeBackgroundColor` - Background color of the active tab.
+ - `inactiveTintColor` - Label and icon color of the inactive tab.
+ - `inactiveBackgroundColor` - Background color of the inactive tab.
+ - `showLabel` - Whether to show label for tab, default is true.
+ - `showIcon` - Whether to show icon for tab, default is true.
+ - `style` - Style object for the tab bar.
+ - `labelStyle` - Style object for the tab label.
+ - `tabStyle` - Style object for the tab.
+ - `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
+ - `adaptive` - Should the tab icons and labels alignment change based on screen size? Defaults to `true` for iOS 11. If `false`, tab icons and labels align vertically all the time. When `true`, tab icons and labels align horizontally on tablet.
+ - `safeAreaInset` - Override the `forceInset` prop for ``. Defaults to `{ bottom: 'always', top: 'never' }`. Available keys are `top | bottom | left | right` provided with the values `'always' | 'never'`.
Example:
@@ -54,17 +54,13 @@ If you want to customize the `tabBarComponent`:
```js
import { createBottomTabNavigator, BottomTabBar } from 'react-navigation-tabs';
-const TabBarComponent = (props) => ( );
+const TabBarComponent = (props) => ;
-const TabScreens = createBottomTabNavigator(
- {
- tabBarComponent: props =>
- ,
- },
-);
+const TabScreens = createBottomTabNavigator({
+ tabBarComponent: (props) => (
+
+ ),
+});
```
## `navigationOptions` for screens inside of the navigator
@@ -101,8 +97,8 @@ ID to locate this tab button in tests.
Callback to handle press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
Useful for adding a custom logic before the transition to the next scene (the tapped one) starts.
diff --git a/versioned_docs/version-2.x/connecting-navigation-prop.md b/versioned_docs/version-2.x/connecting-navigation-prop.md
index 7f24246a255..4dae362c806 100644
--- a/versioned_docs/version-2.x/connecting-navigation-prop.md
+++ b/versioned_docs/version-2.x/connecting-navigation-prop.md
@@ -14,7 +14,14 @@ export default class MyBackButton extends React.Component {
render() {
// This will throw an 'undefined is not a function' exception because the navigation
// prop is undefined.
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
```
@@ -30,7 +37,14 @@ import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
diff --git a/versioned_docs/version-2.x/custom-android-back-button-handling.md b/versioned_docs/version-2.x/custom-android-back-button-handling.md
index 10b48240c14..0b5f3beb7de 100644
--- a/versioned_docs/version-2.x/custom-android-back-button-handling.md
+++ b/versioned_docs/version-2.x/custom-android-back-button-handling.md
@@ -8,7 +8,7 @@ By default, when user presses the Android hardware back button, react-navigation
> If you're looking for an easy-to-use solution, you can check out a community-developed package [react-navigation-backhandler](https://github.com/vonovak/react-navigation-backhandler). The following text shows what the package does under the cover.
-As an example, consider a screen where user is selecting items in a list, and a "selection mode" is active. On a back button press, you would first want the "selection mode" to be deactivated, and the screen should be popped only on the second back button press. The following code snippet demonstrates the situation. We make use of [`BackHandler`](https://reactnative.dev/docs/backhandler.html) which comes with react-native and we [subscribe to navigation lifecycle updates](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle) to add our custom `hardwareBackPress` listener.
+As an example, consider a screen where user is selecting items in a list, and a "selection mode" is active. On a back button press, you would first want the "selection mode" to be deactivated, and the screen should be popped only on the second back button press. The following code snippet demonstrates the situation. We make use of [`BackHandler`](https://reactnative.dev/docs/backhandler.html) which comes with react-native and we [subscribe to navigation lifecycle updates](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle) to add our custom `hardwareBackPress` listener.
Returning `true` from `onBackButtonPressAndroid` denotes that we have handled the event, and react-navigation's listener will not get called, thus not popping the screen. Returning `false` will cause the event to bubble up and react-navigation's listener will pop the screen.
diff --git a/versioned_docs/version-2.x/custom-navigator-overview.md b/versioned_docs/version-2.x/custom-navigator-overview.md
index 009003a8f4c..c1323d63ce7 100644
--- a/versioned_docs/version-2.x/custom-navigator-overview.md
+++ b/versioned_docs/version-2.x/custom-navigator-overview.md
@@ -24,7 +24,7 @@ The navigators render application screens which are just React components.
To learn how to create screens, read about:
- [Screen `navigation` prop](navigation-prop.md) to allow the screen to dispatch navigation actions, such as opening another screen
-- Screen `navigationOptions` to customize how the screen gets presented by the navigator (e.g. [header title](stack-navigator.md#navigationoptions-used-by-stacknavigator), tab label)
+- Screen `navigationOptions` to customize how the screen gets presented by the navigator (e.g. [header title](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator), tab label)
### Calling Navigate on Top Level Component
@@ -38,13 +38,18 @@ const AppNavigator = createStackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
someEvent() {
// call navigate for AppNavigator here:
- this.navigator && this.navigator.dispatch(
- NavigationActions.navigate({ routeName: someRouteName })
- );
+ this.navigator &&
+ this.navigator.dispatch(
+ NavigationActions.navigate({ routeName: someRouteName })
+ );
}
render() {
return (
- { this.navigator = nav; }} />
+ {
+ this.navigator = nav;
+ }}
+ />
);
}
}
diff --git a/versioned_docs/version-2.x/custom-navigators.md b/versioned_docs/version-2.x/custom-navigators.md
index c126e2180f8..39c8a31d016 100644
--- a/versioned_docs/version-2.x/custom-navigators.md
+++ b/versioned_docs/version-2.x/custom-navigators.md
@@ -101,7 +101,7 @@ To help developers implement custom navigators, the following utilities are prov
This utility combines a [router](routers.md) and a [navigation view](navigation-views.md) together in a standard way:
```js
-import {createNavigator} from 'react-navigation';
+import { createNavigator } from 'react-navigation';
const AppNavigator = createNavigator(NavigationView, router, navigationConfig);
```
diff --git a/versioned_docs/version-2.x/deep-linking.md b/versioned_docs/version-2.x/deep-linking.md
index e0e0f6f3854..1659d84a7ac 100644
--- a/versioned_docs/version-2.x/deep-linking.md
+++ b/versioned_docs/version-2.x/deep-linking.md
@@ -4,7 +4,7 @@ title: Deep linking
sidebar_label: Deep linking
---
-In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `mychat://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
+In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `example://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
## Configuration
@@ -36,7 +36,7 @@ You need to specify a scheme for your app. You can register for a scheme in your
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -90,14 +90,14 @@ Next, let's configure our navigation container to extract the path from the app'
```js
const SimpleApp = createStackNavigator({...});
-const prefix = 'mychat://';
+const prefix = 'example://';
const MainApp = () => ;
```
### iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
@@ -116,7 +116,7 @@ In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
In Xcode, open the project at `SimpleApp/ios/SimpleApp.xcodeproj`. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
Now you can press play in Xcode, or re-build on the command line:
@@ -127,10 +127,10 @@ react-native run-ios
To test the URI on the simulator, run the following:
```
-xcrun simctl openurl booted mychat://chat/Eric
+xcrun simctl openurl booted example://chat/Eric
```
-To test the URI on a real device, open Safari and type `mychat://chat/Eric`.
+To test the URI on a real device, open Safari and type `example://chat/Eric`.
### Android
@@ -153,7 +153,7 @@ In `SimpleApp/android/app/src/main/AndroidManifest.xml`, do these followings adj
-
+
```
@@ -167,7 +167,7 @@ react-native run-android
To test the intent handling in Android, run the following:
```
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/Eric" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/Eric" com.simpleapp
```
## Disable deep linking
diff --git a/versioned_docs/version-2.x/drawer-actions.md b/versioned_docs/version-2.x/drawer-actions.md
index b6e23b40109..44f67c73056 100644
--- a/versioned_docs/version-2.x/drawer-actions.md
+++ b/versioned_docs/version-2.x/drawer-actions.md
@@ -8,14 +8,14 @@ sidebar_label: DrawerActions
The following actions are supported:
-* [openDrawer](#openDrawer) - open the drawer
-* [closeDrawer](#closeDrawer) - close the drawer
-* [toggleDrawer](#toggleDrawer) - toggle the state, ie. switch from closed to open and vice versa
+- openDrawer - open the drawer
+- closeDrawer - close the drawer
+- toggleDrawer - toggle the state, ie. switch from closed to open and vice versa
### Usage
```js
import { DrawerActions } from 'react-navigation-drawer';
-this.props.navigation.dispatch(DrawerActions.toggleDrawer())
+this.props.navigation.dispatch(DrawerActions.toggleDrawer());
```
diff --git a/versioned_docs/version-2.x/drawer-navigator.md b/versioned_docs/version-2.x/drawer-navigator.md
index ee1059bb19e..1f4681a026c 100644
--- a/versioned_docs/version-2.x/drawer-navigator.md
+++ b/versioned_docs/version-2.x/drawer-navigator.md
@@ -5,7 +5,7 @@ sidebar_label: createDrawerNavigator
---
```js
-createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
+createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig);
```
### RouteConfigs
@@ -37,7 +37,10 @@ import { DrawerItems, SafeAreaView } from 'react-navigation';
const CustomDrawerContentComponent = (props) => (
-
+
diff --git a/versioned_docs/version-2.x/glossary-of-terms.md b/versioned_docs/version-2.x/glossary-of-terms.md
index d09362973b4..d55b1058fc2 100644
--- a/versioned_docs/version-2.x/glossary-of-terms.md
+++ b/versioned_docs/version-2.x/glossary-of-terms.md
@@ -18,7 +18,7 @@ A screen component is a component that we use in our route configuration.
const AppNavigator = createStackNavigator(
{
Home: {
- screen: HomeScreen, // <----
+ screen: HomeScreen, // <----
},
Details: {
screen: DetailsScreen, // <----
@@ -32,7 +32,7 @@ const AppNavigator = createStackNavigator(
The suffix `Screen` in the component name is entirely optional, but a frequently used convention; we could call it `CasaPantalla` and this would work just the same.
-We saw earlier that our screen components are provided with the `navigation` prop. It's important to note that *this only happens if the screen is rendered as a route by React Navigation* (for example, in response to `this.props.navigation.navigate`). For example, if we render `DetailsScreen` as a child of `HomeScreen`, then `DetailsScreen` won't be provided with the `navigation` prop, and when you press the "Go to Details... again" button on the Home screen, the app will throw one of the quintessential JavaScript exceptions "undefined is not an object".
+We saw earlier that our screen components are provided with the `navigation` prop. It's important to note that _this only happens if the screen is rendered as a route by React Navigation_ (for example, in response to `this.props.navigation.navigate`). For example, if we render `DetailsScreen` as a child of `HomeScreen`, then `DetailsScreen` won't be provided with the `navigation` prop, and when you press the "Go to Details... again" button on the Home screen, the app will throw one of the quintessential JavaScript exceptions "undefined is not an object".
```js
class HomeScreen extends React.Component {
diff --git a/versioned_docs/version-2.x/handling-iphonex.md b/versioned_docs/version-2.x/handling-iphonex.md
index 61cfdb60008..9dcd180b364 100644
--- a/versioned_docs/version-2.x/handling-iphonex.md
+++ b/versioned_docs/version-2.x/handling-iphonex.md
@@ -39,12 +39,8 @@ class MyHomeScreen extends Component {
render() {
return (
-
- This is top text.
-
-
- This is bottom text.
-
+ This is top text.
+ This is bottom text.
);
}
@@ -75,12 +71,8 @@ In some cases you might need more control over which paddings are applied. For e
```javascript
-
- This is top text.
-
-
- This is bottom text.
-
+ This is top text.
+ This is bottom text.
```
diff --git a/versioned_docs/version-2.x/headers.md b/versioned_docs/version-2.x/headers.md
index c08a31d16f0..e4c4d144f98 100644
--- a/versioned_docs/version-2.x/headers.md
+++ b/versioned_docs/version-2.x/headers.md
@@ -63,11 +63,11 @@ We only needed the `navigation` prop in the above example but you may in some ca
It's often necessary to update the `navigationOptions` configuration for the active screen from the mounted screen component itself. We can do this using `this.props.navigation.setParams`
```js
- /* Inside of render() */
- this.props.navigation.setParams({otherParam: 'Updated!'})}
- />
+/* Inside of render() */
+ this.props.navigation.setParams({ otherParam: 'Updated!' })}
+/>
```
→ Run this code
@@ -202,11 +202,11 @@ class HomeScreen extends React.Component {
## Additional configuration
-You can read the full list of available `navigationOptions` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+You can read the full list of available `navigationOptions` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator).
## Summary
-- You can customize the header inside of the `navigationOptions` static property on your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+- You can customize the header inside of the `navigationOptions` static property on your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator).
- The `navigationOptions` static property can be an object or a function. When it is a function, it is provided with an object with the `navigation` prop, `screenProps`, and `navigationOptions` on it.
- You can also specify shared `navigationOptions` in the stack navigator configuration when you initialize it. The static property takes precedence over that configuration.
- [Full source of what we have built so far](https://snack.expo.io/@react-navigation/custom-header-title-component-v2).
diff --git a/versioned_docs/version-2.x/hello-react-navigation.md b/versioned_docs/version-2.x/hello-react-navigation.md
index 74eac8e37a7..343f7fda636 100644
--- a/versioned_docs/version-2.x/hello-react-navigation.md
+++ b/versioned_docs/version-2.x/hello-react-navigation.md
@@ -33,7 +33,7 @@ class HomeScreen extends React.Component {
export default createStackNavigator({
Home: {
- screen: HomeScreen
+ screen: HomeScreen,
},
});
```
@@ -51,7 +51,7 @@ In React Native, the component exported from `App.js` is the entry point (or roo
```js
const RootStack = createStackNavigator({
Home: {
- screen: HomeScreen
+ screen: HomeScreen,
},
});
@@ -68,7 +68,7 @@ Given that the only route configuration we have for `Home` is the screen compone
```js
const RootStack = createStackNavigator({
- Home: HomeScreen
+ Home: HomeScreen,
});
```
@@ -106,8 +106,8 @@ Now our stack has two _routes_, a `Home` route and a `Details` route. The `Home`
## Summary
-* React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens.
-* `createStackNavigator` is a function that takes a route configuration object and an options object and returns a React component.
-* The keys in the route configuration object are the route names and the values are the configuration for that route. The only required property on the configuration is the `screen` (the component to use for the route).
-* To specify what the initial route in a stack is, provide an `initialRouteName` on the stack options object.
-* [Full source of what we have built so far](https://snack.expo.io/@react-navigation/hello-react-navigation-v2).
+- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens.
+- `createStackNavigator` is a function that takes a route configuration object and an options object and returns a React component.
+- The keys in the route configuration object are the route names and the values are the configuration for that route. The only required property on the configuration is the `screen` (the component to use for the route).
+- To specify what the initial route in a stack is, provide an `initialRouteName` on the stack options object.
+- [Full source of what we have built so far](https://snack.expo.io/@react-navigation/hello-react-navigation-v2).
diff --git a/versioned_docs/version-2.x/material-bottom-tab-navigator.md b/versioned_docs/version-2.x/material-bottom-tab-navigator.md
index 56d88f11c35..a7bc07307ee 100644
--- a/versioned_docs/version-2.x/material-bottom-tab-navigator.md
+++ b/versioned_docs/version-2.x/material-bottom-tab-navigator.md
@@ -17,7 +17,10 @@ npm install react-navigation-material-bottom-tabs react-native-paper
This API also requires that you install `react-native-vector-icons`! If you are using Expo, it will just work out of the box. Otherwise, [follow these installation instructions](https://github.com/oblador/react-native-vector-icons#installation).
```js
-createMaterialBottomTabNavigator(RouteConfigs, MaterialBottomTabNavigatorConfig);
+createMaterialBottomTabNavigator(
+ RouteConfigs,
+ MaterialBottomTabNavigatorConfig
+);
```
This library uses the [`BottomNavigation` component from `react-native-paper`](https://callstack.github.io/react-native-paper/bottom-navigation.html). It doesn't include the whole `react-native-paper` library in your bundle, so you don't need to worry about it.
@@ -28,30 +31,33 @@ The route configs object is a mapping from route name to a route config.
## MaterialBottomTabNavigatorConfig
-* `shifting` - Whether the shifting style is used, the active tab appears wider and the inactive tabs won't have a label. By default, this is `true` when you have more than 3 tabs.
-* `labeled` - Whether to show labels in tabs. When `false`, only icons will be displayed.
-* `activeColor` - Custom color for icon and label in the active tab.
-* `inactiveColor` - Custom color for icon and label in the inactive tab.
-* `barStyle` - Style for the bottom navigation bar. You can set a bottom padding here if you have a translucent navigation bar on Android: `barStyle={{ paddingBottom: 48 }}`.
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
+- `shifting` - Whether the shifting style is used, the active tab appears wider and the inactive tabs won't have a label. By default, this is `true` when you have more than 3 tabs.
+- `labeled` - Whether to show labels in tabs. When `false`, only icons will be displayed.
+- `activeColor` - Custom color for icon and label in the active tab.
+- `inactiveColor` - Custom color for icon and label in the inactive tab.
+- `barStyle` - Style for the bottom navigation bar. You can set a bottom padding here if you have a translucent navigation bar on Android: `barStyle={{ paddingBottom: 48 }}`.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
Example:
```js
-export default createMaterialBottomTabNavigator({
- Album: { screen: Album },
- Library: { screen: Library },
- History: { screen: History },
- Cart: { screen: Cart },
-}, {
- initialRouteName: 'Album',
- activeColor: '#f0edf6',
- inactiveColor: '#3e2465',
- barStyle: { backgroundColor: '#694fad' },
-});
+export default createMaterialBottomTabNavigator(
+ {
+ Album: { screen: Album },
+ Library: { screen: Library },
+ History: { screen: History },
+ Cart: { screen: Cart },
+ },
+ {
+ initialRouteName: 'Album',
+ activeColor: '#f0edf6',
+ inactiveColor: '#3e2465',
+ barStyle: { backgroundColor: '#694fad' },
+ }
+);
```
## `navigationOptions` for screens inside of the navigator
@@ -84,8 +90,8 @@ ID to locate this tab button in tests.
Callback to handle press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
Useful for adding a custom logic before the transition to the next scene (the tapped one) starts.
diff --git a/versioned_docs/version-2.x/material-top-tab-navigator.md b/versioned_docs/version-2.x/material-top-tab-navigator.md
index 7c123c24668..9448d9dc08d 100644
--- a/versioned_docs/version-2.x/material-top-tab-navigator.md
+++ b/versioned_docs/version-2.x/material-top-tab-navigator.md
@@ -16,33 +16,33 @@ The route configs object is a mapping from route name to a route config.
## TabNavigatorConfig
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
-* `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`, default is `top`.
-* `swipeEnabled` - Whether to allow swiping between tabs.
-* `animationEnabled` - Whether to animate when changing tabs.
-* `lazy` - Defaults to `false`. If `true`, tabs are rendered only when they are made active or on peek swipe. When `false`, all tabs are rendered immediately.
-* `optimizationsEnabled` - Whether to wrap scenes into [` `](https://github.com/react-navigation/react-navigation-tabs/blob/master/src/views/ResourceSavingScene.js) to move the scene out of the screen once it's unfocused, it improves memory usage.
-* `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view#avoid-one-frame-delay) rendering.
-* `tabBarComponent` - Optional, override the component to use as the tab bar.
-* `tabBarOptions` - An object with the following properties:
- * `activeTintColor` - Label and icon color of the active tab.
- * `inactiveTintColor` - Label and icon color of the inactive tab.
- * `showIcon` - Whether to show icon for tab, default is false.
- * `showLabel` - Whether to show label for tab, default is true.
- * `upperCaseLabel` - Whether to make label uppercase, default is true.
- * `pressColor` - Color for material ripple (Android >= 5.0 only).
- * `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
- * `scrollEnabled` - Whether to enable scrollable tabs.
- * `tabStyle` - Style object for the tab.
- * `indicatorStyle` - Style object for the tab indicator (line at the bottom of the tab).
- * `labelStyle` - Style object for the tab label.
- * `iconStyle` - Style object for the tab icon.
- * `style` - Style object for the tab bar.
- * `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
- * `renderIndicator` - Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
+- `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`, default is `top`.
+- `swipeEnabled` - Whether to allow swiping between tabs.
+- `animationEnabled` - Whether to animate when changing tabs.
+- `lazy` - Defaults to `false`. If `true`, tabs are rendered only when they are made active or on peek swipe. When `false`, all tabs are rendered immediately.
+- `optimizationsEnabled` - Whether to wrap scenes into [` `](https://github.com/react-navigation/react-navigation-tabs/blob/master/src/views/ResourceSavingScene.js) to move the scene out of the screen once it's unfocused, it improves memory usage.
+- `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view#avoid-one-frame-delay) rendering.
+- `tabBarComponent` - Optional, override the component to use as the tab bar.
+- `tabBarOptions` - An object with the following properties:
+ - `activeTintColor` - Label and icon color of the active tab.
+ - `inactiveTintColor` - Label and icon color of the inactive tab.
+ - `showIcon` - Whether to show icon for tab, default is false.
+ - `showLabel` - Whether to show label for tab, default is true.
+ - `upperCaseLabel` - Whether to make label uppercase, default is true.
+ - `pressColor` - Color for material ripple (Android >= 5.0 only).
+ - `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
+ - `scrollEnabled` - Whether to enable scrollable tabs.
+ - `tabStyle` - Style object for the tab.
+ - `indicatorStyle` - Style object for the tab indicator (line at the bottom of the tab).
+ - `labelStyle` - Style object for the tab label.
+ - `iconStyle` - Style object for the tab icon.
+ - `style` - Style object for the tab bar.
+ - `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
+ - `renderIndicator` - Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
Example:
@@ -90,7 +90,7 @@ ID to locate this tab button in tests.
Callback to handle press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
Useful for adding a custom logic before the transition to the next scene (the tapped one) starts.
diff --git a/versioned_docs/version-2.x/navigating-without-navigation-prop.md b/versioned_docs/version-2.x/navigating-without-navigation-prop.md
index 7a6bc43e387..d90efc9beee 100644
--- a/versioned_docs/version-2.x/navigating-without-navigation-prop.md
+++ b/versioned_docs/version-2.x/navigating-without-navigation-prop.md
@@ -13,7 +13,9 @@ You can get access to a navigator through a `ref` and pass it to the `Navigation
import NavigationService from './NavigationService';
-const TopLevelNavigator = createStackNavigator({ /* ... */ })
+const TopLevelNavigator = createStackNavigator({
+ /* ... */
+});
class App extends React.Component {
// ...
@@ -21,7 +23,7 @@ class App extends React.Component {
render() {
return (
{
+ ref={(navigatorRef) => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
diff --git a/versioned_docs/version-2.x/navigating.md b/versioned_docs/version-2.x/navigating.md
index c2f527ef8bf..4fce3574976 100644
--- a/versioned_docs/version-2.x/navigating.md
+++ b/versioned_docs/version-2.x/navigating.md
@@ -48,8 +48,8 @@ class HomeScreen extends React.Component {
Let's break this down:
-* `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
-* `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
+- `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
+- `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
> If we call `this.props.navigation.navigate` with a route name that we haven't defined on a stack navigator, nothing will happen. Said another way, we can only navigate to routes that have been defined on our stack navigator — we cannot navigate to an arbitrary component.
@@ -128,9 +128,9 @@ Another common requirement is to be able to go back _multiple_ screens -- for ex
## Summary
-* `this.props.navigation.navigate('RouteName')` pushes a new route to the stack navigator if it's not already in the stack, otherwise it jumps to that screen.
-* We can call `this.props.navigation.push('RouteName')` as many times as we like and it will continue pushing routes.
-* The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
-* You can go back to an existing screen in the stack with `this.props.navigation.navigate('RouteName')`, and you can go back to the first screen in the stack with `this.props.navigation.popToTop()`.
-* The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
-* [Full source of what we have built so far](https://snack.expo.io/@react-navigation/going-back-v2).
+- `this.props.navigation.navigate('RouteName')` pushes a new route to the stack navigator if it's not already in the stack, otherwise it jumps to that screen.
+- We can call `this.props.navigation.push('RouteName')` as many times as we like and it will continue pushing routes.
+- The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
+- You can go back to an existing screen in the stack with `this.props.navigation.navigate('RouteName')`, and you can go back to the first screen in the stack with `this.props.navigation.popToTop()`.
+- The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
+- [Full source of what we have built so far](https://snack.expo.io/@react-navigation/going-back-v2).
diff --git a/versioned_docs/version-2.x/navigation-actions.md b/versioned_docs/version-2.x/navigation-actions.md
index 3ac71e92270..a0ff2cc460d 100644
--- a/versioned_docs/version-2.x/navigation-actions.md
+++ b/versioned_docs/version-2.x/navigation-actions.md
@@ -10,10 +10,9 @@ Note that if you want to dispatch react-navigation actions you should use the ac
The following actions are supported:
-* [Navigate](#navigate) - Navigate to another route
-* [Back](#back) - Go back to previous state
-* [Set Params](#setparams) - Set Params for given route
-* [Init](#init) - Used to initialize first state if state is undefined
+- [Navigate](#navigate) - Navigate to another route
+- [Back](#back) - Go back to previous state
+- [Set Params](#setparams) - Set Params for given route
For actions specific to a StackNavigator, see [StackActions](stack-actions.md).
@@ -23,10 +22,10 @@ The action creator functions define `toString()` to return the action type, whic
The `navigate` action will update the current state with the result of a `navigate` action.
-* `routeName` - _String_ - Required - A destination routeName that has been registered somewhere in the app's router
-* `params` - _Object_ - Optional - Params to merge into the destination route
-* `action` - _Object_ - Optional - (advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the actions described in this doc can be set as a sub-action.
-* `key` - _String_ - Optional - The identifier for the route to navigate to. Navigate back to this route if it already exists
+- `routeName` - _String_ - Required - A destination routeName that has been registered somewhere in the app's router
+- `params` - _Object_ - Optional - Params to merge into the destination route
+- `action` - _Object_ - Optional - (advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the actions described in this doc can be set as a sub-action.
+- `key` - _String_ - Optional - The identifier for the route to navigate to. Navigate back to this route if it already exists
```js
import { NavigationActions } from 'react-navigation';
@@ -46,7 +45,7 @@ this.props.navigation.dispatch(navigateAction);
Go back to previous screen and close current screen. `back` action creator takes in one optional parameter:
-* `key` - _string or null_ - optional - If set, navigation will go back from the given key. If null, navigation will go back anywhere.
+- `key` - _string or null_ - optional - If set, navigation will go back from the given key. If null, navigation will go back anywhere.
```js
import { NavigationActions } from 'react-navigation';
@@ -61,8 +60,8 @@ this.props.navigation.dispatch(backAction);
When dispatching `setParams`, the router will produce a new state that has changed the params of a particular route, as identified by the key
-* `params` - _object_ - required - New params to be merged into existing route params
-* `key` - _string_ - required - Route key that should get the new params
+- `params` - _object_ - required - New params to be merged into existing route params
+- `key` - _string_ - required - Route key that should get the new params
```js
import { NavigationActions } from 'react-navigation';
diff --git a/versioned_docs/version-2.x/navigation-events.md b/versioned_docs/version-2.x/navigation-events.md
index 802305cd658..a258d361e33 100644
--- a/versioned_docs/version-2.x/navigation-events.md
+++ b/versioned_docs/version-2.x/navigation-events.md
@@ -8,13 +8,13 @@ sidebar_label: NavigationEvents
### Component props
-* `navigation` - navigation props (optional, defaults to reading from React context)
-* `onWillFocus` - event listener
-* `onDidFocus` - event listener
-* `onWillBlur` - event listener
-* `onDidBlur` - event listener
+- `navigation` - navigation props (optional, defaults to reading from React context)
+- `onWillFocus` - event listener
+- `onDidFocus` - event listener
+- `onWillBlur` - event listener
+- `onDidBlur` - event listener
-The event listener is the same as the imperative [`navigation.addListener(...)`](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle) API.
+The event listener is the same as the imperative [`navigation.addListener(...)`](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle) API.
### Example
@@ -26,10 +26,10 @@ import { NavigationEvents } from 'react-navigation';
const MyScreen = () => (
console.log('will focus',payload)}
- onDidFocus={payload => console.log('did focus',payload)}
- onWillBlur={payload => console.log('will blur',payload)}
- onDidBlur={payload => console.log('did blur',payload)}
+ onWillFocus={(payload) => console.log('will focus', payload)}
+ onDidFocus={(payload) => console.log('did focus', payload)}
+ onWillBlur={(payload) => console.log('will blur', payload)}
+ onDidBlur={(payload) => console.log('did blur', payload)}
/>
{/*
Your view code
diff --git a/versioned_docs/version-2.x/navigation-key.md b/versioned_docs/version-2.x/navigation-key.md
index 6cfff3dc734..941c6189082 100644
--- a/versioned_docs/version-2.x/navigation-key.md
+++ b/versioned_docs/version-2.x/navigation-key.md
@@ -10,21 +10,21 @@ The `key` parameter comes up repeatedly across different navigation functions. L
If no key is provided, `StackRouter` will behave as follows:
-* if a route with the given name already exists in the state, `StackRouter` will jump to the existing route, along with setting the new parameters.
-* if no such route exists, `StackRouter` will push it onto the stack
+- if a route with the given name already exists in the state, `StackRouter` will jump to the existing route, along with setting the new parameters.
+- if no such route exists, `StackRouter` will push it onto the stack
If, however, you want to push several instances of the same route, you can do so by providing a unique `key` parameter each time you call `navigate`, or you can use the `push` action available on `StackRouter`. See the related [RFC](https://github.com/react-navigation/rfcs/blob/master/text/0004-less-pushy-navigate.md) for more background.
> Note: the behavior of `navigate` without a `key` is significantly different in the 1.x series of releases. Read more about it [here](https://gist.github.com/vonovak/ef72f5efe1d36742de8968ff6a708985).
-### Usage with [`reset`](navigation-actions.md#reset)
+### Usage with [`reset`](stack-actions.md#reset)
When resetting, `key` is also optional and can be a string or `null`. If set, the navigator with the given key will reset. If `null`, the root navigator will reset. You can obtain a route's navigator key by calling `this.props.navigation.dangerouslyGetParent().state.key`. Reason why the function is called `dangerouslyGetParent` is to warn developers against overusing it to eg. get parent of parent and other hard-to-follow patterns.
-### Usage with [`replace`](navigation-actions.md#replace)
+### Usage with [`replace`](stack-actions.md#replace)
With the `replace` navigation action, `key` is a required parameter used for identifying the route to be replaced. If you use the helper function `this.props.navigation.replace`, we will automatically substitute the key of the current route.
### Usage with `goBack`
-Please refer to the [`goBack docs`](navigation-prop.md#goback-close-the-active-screen-and-move-back) for a detailed explanation.
+Please refer to the [`goBack docs`](navigation-prop.md#goback---close-the-active-screen-and-move-back) for a detailed explanation.
diff --git a/versioned_docs/version-2.x/navigation-lifecycle.md b/versioned_docs/version-2.x/navigation-lifecycle.md
index bc1c1abcc1d..e6210d5f11e 100644
--- a/versioned_docs/version-2.x/navigation-lifecycle.md
+++ b/versioned_docs/version-2.x/navigation-lifecycle.md
@@ -29,12 +29,10 @@ const SettingsStack = createStackNavigator({
Profile: ProfileScreen,
});
-const TabNavigator = createBottomTabNavigator(
- {
- Home: HomeStack,
- Settings: SettingsStack,
- }
-);
+const TabNavigator = createBottomTabNavigator({
+ Home: HomeStack,
+ Settings: SettingsStack,
+});
```
We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the tab bar to switch to the `SettingsScreen` and navigate to `ProfileScreen`. After this sequence of operations is done, all 4 of the screens are mounted! If you use the tab bar to switch back to the `HomeStack`, you'll notice you'll be presented with the `DetailsScreen` - the navigation state of the `HomeStack` has been preserved!
@@ -43,7 +41,7 @@ We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the ta
Now that we understand how React lifecycle methods work in React Navigation, let's answer the question we asked at the beginning: "How do we find out that a user is leaving it or coming back to it?"
-React Navigation emits events to screen components that subscribe to them. There are four different events that you can subscribe to: `willFocus`, `willBlur`, `didFocus` and `didBlur`. Read more about them in the [API reference](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle).
+React Navigation emits events to screen components that subscribe to them. There are four different events that you can subscribe to: `willFocus`, `willBlur`, `didFocus` and `didBlur`. Read more about them in the [API reference](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle).
Many of your use cases may be covered with the [`withNavigationFocus` HOC](with-navigation-focus.md) or the [` ` component](navigation-events.md) which are a little more straightforward to use.
diff --git a/versioned_docs/version-2.x/navigation-options-resolution.md b/versioned_docs/version-2.x/navigation-options-resolution.md
index d0da213598d..746b673e557 100644
--- a/versioned_docs/version-2.x/navigation-options-resolution.md
+++ b/versioned_docs/version-2.x/navigation-options-resolution.md
@@ -88,13 +88,16 @@ We also know that `createStackNavigator` and related functions return React comp
Navigators are initialized with `create*Navigator(routeConfig, navigatorConfig)`. Inside of `navigatorConfig` we can add a `navigationOptions` property. These `navigationOptions` are the default options for screens within that navigator ([read more about sharing common navigationOptions](headers.md#sharing-common-navigationoptions-across-screens)), they do not refer to the `navigationOptions` for that navigator — as we have seen above, we set the `navigationOptions` property directly on the navigator for that use case.
```js
-const HomeStack = createStackNavigator({ A }, {
- // This is the default for screens in the stack, so `A` will
- // use this title unless it overrides it
- navigationOptions: {
- title: 'Welcome'
+const HomeStack = createStackNavigator(
+ { A },
+ {
+ // This is the default for screens in the stack, so `A` will
+ // use this title unless it overrides it
+ navigationOptions: {
+ title: 'Welcome',
+ },
}
-})
+);
// These are the options that are used by the navigator that renders
// the HomeStack, in our example above this is a tab navigator.
@@ -105,7 +108,7 @@ HomeStack.navigationOptions = {
We understand that overloading the naming here is a little bit confusing. Please [open a RFC](https://github.com/react-navigation/rfcs) if you have a suggestion about how we can make this API easier to learn and work with.
-# A stack contains a tab navigator and you want to set the title on the stack header
+## A stack contains a tab navigator and you want to set the title on the stack header
Imagine the following configuration:
@@ -174,7 +177,7 @@ Using this configuration, the `headerTitle` or `title` from `navigationOptions`
Additionally, you can push new screens to the feed and profile stacks without hiding the tab bar by adding more routes to those stacks. If you want to push screens on top of the tab bar, then you can add them to the `AppNavigator` stack.
-# A tab navigator contains a stack and you want to hide the tab bar on specific screens
+## A tab navigator contains a stack and you want to hide the tab bar on specific screens
Similar to the example above where a stack contains a tab navigator, we can solve this in two ways: add `navigationOptions` to our tab navigator to set the tab bar to hidden depending on which route is active in the child stack, or we can move the tab navigator inside of the stack.
@@ -244,7 +247,7 @@ const AppNavigator = createSwitchNavigator({
});
```
-# A drawer has a stack inside of it and you want to lock the drawer on certain screens
+## A drawer has a stack inside of it and you want to lock the drawer on certain screens
This is conceptually identical to having a tab with a stack inside of it (read that above if you have not already), where you want to hide the tab bar on certain screens. The only difference is that rather than using `tabBarVisible` you will use `drawerLockMode`.
diff --git a/versioned_docs/version-2.x/navigation-prop.md b/versioned_docs/version-2.x/navigation-prop.md
index c45040d67e2..a34fe0d9e0d 100644
--- a/versioned_docs/version-2.x/navigation-prop.md
+++ b/versioned_docs/version-2.x/navigation-prop.md
@@ -6,16 +6,16 @@ sidebar_label: Navigation prop
Each `screen` component in your app is provided with the `navigation` prop automatically. The prop contains various convenience functions that dispatch navigation actions on the route's router. It looks like this:
-* `this.props.navigation`
- * `navigate` - go to another screen, figures out the action it needs to take to do it
- * `goBack` - close active screen and move back in the stack
- * `addListener` - subscribe to updates to navigation lifecycle
- * `isFocused` - function that returns `true` if the screen is focused and `false` otherwise.
- * `state` - current state/routes
- * `setParams` - make changes to route's params
- * `getParam` - get a specific param with fallback
- * `dispatch` - send an action to router
- * `dangerouslyGetParent` - function that returns the parent navigator, if any
+- `this.props.navigation`
+ - `navigate` - go to another screen, figures out the action it needs to take to do it
+ - `goBack` - close active screen and move back in the stack
+ - `addListener` - subscribe to updates to navigation lifecycle
+ - `isFocused` - function that returns `true` if the screen is focused and `false` otherwise.
+ - `state` - current state/routes
+ - `setParams` - make changes to route's params
+ - `getParam` - get a specific param with fallback
+ - `dispatch` - send an action to router
+ - `dangerouslyGetParent` - function that returns the parent navigator, if any
It's important to highlight the `navigation` prop is _not_ passed in to _all_ components; only `screen` components receive this prop automatically! React Navigation doesn't do anything magic here. For example, if you were to define a `MyBackButton` component and render it as a child of a screen component, you would not be able to access the `navigation` prop on it. If, however, you wish to access the `navigation` prop in any of your components, you may use the [`withNavigation`](with-navigation.md) HOC.
@@ -25,20 +25,20 @@ There are several additional functions present on `this.props.navigation` based
If the navigator is a stack navigator, several alternatives to `navigate` and `goBack` are provided and you can use whichever you prefer. The functions are:
-* `this.props.navigation`
- * `push` - push a new route onto the stack
- * `pop` - go back in the stack
- * `popToTop` - go to the top of the stack
- * `replace` - replace the current route with a new one
- * `reset` - wipe the navigator state and replace it with the result of several actions
- * `dismiss` - dismiss the current stack
+- `this.props.navigation`
+ - `push` - push a new route onto the stack
+ - `pop` - go back in the stack
+ - `popToTop` - go to the top of the stack
+ - `replace` - replace the current route with a new one
+ - `reset` - wipe the navigator state and replace it with the result of several actions
+ - `dismiss` - dismiss the current stack
If the navigator is a drawer navigator, the following are also available:
-* `this.props.navigation`
- * `openDrawer` - open the drawer
- * `closeDrawer` - close the drawer
- * `toggleDrawer` - toggle the state, ie. switch from closed to open and vice versa
+- `this.props.navigation`
+ - `openDrawer` - open the drawer
+ - `closeDrawer` - close the drawer
+ - `toggleDrawer` - toggle the state, ie. switch from closed to open and vice versa
## Common API reference
@@ -54,10 +54,10 @@ OR
`navigation.navigate(routeName, params, action)`
-* `routeName` - A destination routeName that has been registered somewhere in the app's router
-* `params` - Params to merge into the destination route
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
-* `key` - Optional identifier of what route to navigate to. Navigate **back** to this route, if it already exists
+- `routeName` - A destination routeName that has been registered somewhere in the app's router
+- `params` - Params to merge into the destination route
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
+- `key` - Optional identifier of what route to navigate to. Navigate **back** to this route, if it already exists
```js
class HomeScreen extends React.Component {
@@ -106,10 +106,10 @@ class HomeScreen extends React.Component {
Consider the following navigation stack history:
```javascript
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_A});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_B});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_C});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_D});
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_A });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_B });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_C });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_D });
```
Now you are on _screen D_ and want to go back to _screen A_ (popping D, C, and B).
@@ -125,17 +125,17 @@ Alternatively, as _screen A_ is the top of the stack, you can use `navigation.po
React Navigation emits events to screen components that subscribe to them:
-* `willFocus` - the screen will focus
-* `didFocus` - the screen focused (if there was a transition, the transition completed)
-* `willBlur` - the screen will be unfocused
-* `didBlur` - the screen unfocused (if there was a transition, the transition completed)
+- `willFocus` - the screen will focus
+- `didFocus` - the screen focused (if there was a transition, the transition completed)
+- `willBlur` - the screen will be unfocused
+- `didBlur` - the screen unfocused (if there was a transition, the transition completed)
Example:
```javascript
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
- payload => {
+ (payload) => {
console.debug('didBlur', payload);
}
);
@@ -239,19 +239,19 @@ The following actions will work within any stack navigator:
Similar to navigate, push will move you forward to a new route in the stack. This differs from `navigate` in that `navigate` will pop back to earlier in the stack if a route of the given name is already present there. `push` will always add on top, so a route can be present multiple times.
```js
-navigation.push(routeName, params, action)
+navigation.push(routeName, params, action);
```
-* `routeName` - A destination routeName that has been registered somewhere in the app's router.
-* `params` - Params to merge into the destination route.
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
+- `routeName` - A destination routeName that has been registered somewhere in the app's router.
+- `params` - Params to merge into the destination route.
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
### Pop
Take you to the previous screen in the stack. If you provide a number, `n`, it will specify how many screens to take you back within the stack.
```js
-navigation.pop(n)
+navigation.pop(n);
```
### PopToTop
@@ -259,7 +259,7 @@ navigation.pop(n)
Call this to jump back to the top route in the stack, dismissing all other screens.
```js
-navigation.popToTop()
+navigation.popToTop();
```
### Replace
@@ -267,7 +267,7 @@ navigation.popToTop()
Call this to replace the current screen with the given route, with params and sub-action.
```js
-navigation.replace(routeName, params, action)
+navigation.replace(routeName, params, action);
```
### Reset
@@ -275,7 +275,7 @@ navigation.replace(routeName, params, action)
Wipe the navigator state and replace it with the result of several actions.
```js
-navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0)
+navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0);
```
### Dismiss
@@ -283,7 +283,7 @@ navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0)
Call this if you're in a nested (child) stack and want to dismiss the entire stack, returning to the parent stack.
```js
-navigation.dismiss()
+navigation.dismiss();
```
## Advanced API Reference
@@ -330,9 +330,8 @@ class UserCreateScreen extends Component {
return {
title: 'New User',
- gesturesEnabled
+ gesturesEnabled,
};
};
}
-
```
diff --git a/versioned_docs/version-2.x/params.md b/versioned_docs/version-2.x/params.md
index 197a7647e27..08099ad53ac 100644
--- a/versioned_docs/version-2.x/params.md
+++ b/versioned_docs/version-2.x/params.md
@@ -54,7 +54,8 @@ class DetailsScreen extends React.Component {
onPress={() =>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
{
const nextState = AppNavigator.router.getStateForAction(action, state);
@@ -140,19 +142,19 @@ const navReducer = (state = initialState, action) => {
By using the following snippet, your nav component will be aware of the back button press actions and will correctly interact with your stack. This is really useful on Android.
```es6
-import React from "react";
-import { BackHandler } from "react-native";
-import { NavigationActions } from "react-navigation";
+import React from 'react';
+import { BackHandler } from 'react-native';
+import { NavigationActions } from 'react-navigation';
/* your other setup code here! this is not a runnable snippet */
class ReduxNavigation extends React.Component {
componentDidMount() {
- BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
+ BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
componentWillUnmount() {
- BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
+ BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress = () => {
diff --git a/versioned_docs/version-2.x/routers.md b/versioned_docs/version-2.x/routers.md
index 69c82d9021e..968631c8416 100644
--- a/versioned_docs/version-2.x/routers.md
+++ b/versioned_docs/version-2.x/routers.md
@@ -35,12 +35,15 @@ See the [Custom Router API spec](custom-routers.md) to learn about the API of `S
To override navigation behavior, you can override the navigation state logic in `getStateForAction`, and manually manipulate the `routes` and `index`.
```js
-const MyApp = createStackNavigator({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
+const MyApp = createStackNavigator(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
const defaultGetStateForAction = MyApp.router.getStateForAction;
@@ -48,8 +51,8 @@ MyApp.router.getStateForAction = (action, state) => {
if (state && action.type === 'PushTwoProfiles') {
const routes = [
...state.routes,
- {key: 'A', routeName: 'Profile', params: { name: action.name1 }},
- {key: 'B', routeName: 'Profile', params: { name: action.name2 }},
+ { key: 'A', routeName: 'Profile', params: { name: action.name1 } },
+ { key: 'B', routeName: 'Profile', params: { name: action.name2 } },
];
return {
...state,
@@ -66,14 +69,17 @@ MyApp.router.getStateForAction = (action, state) => {
Sometimes you may want to prevent some navigation activity, depending on your route.
```js
-import { NavigationActions } from 'react-navigation'
+import { NavigationActions } from 'react-navigation';
-const MyStackRouter = StackRouter({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
+const MyStackRouter = StackRouter(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
const defaultGetStateForAction = MyStackRouter.router.getStateForAction;
@@ -97,22 +103,23 @@ MyStackRouter.router.getStateForAction = (action, state) => {
Perhaps your app has a unique URI which the built-in routers cannot handle. You can always extend the router `getActionForPathAndParams`.
```js
-import { NavigationActions } from 'react-navigation'
+import { NavigationActions } from 'react-navigation';
-const MyApp = createStackNavigator({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
-const previousGetActionForPathAndParams = MyApp.router.getActionForPathAndParams;
+const MyApp = createStackNavigator(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
+const previousGetActionForPathAndParams =
+ MyApp.router.getActionForPathAndParams;
Object.assign(MyApp.router, {
getActionForPathAndParams(path, params) {
- if (
- path === 'my/custom/path' &&
- params.magic === 'yes'
- ) {
+ if (path === 'my/custom/path' && params.magic === 'yes') {
// returns a profile navigate action for /my/custom/path?magic=yes
return NavigationActions.navigate({
routeName: 'Profile',
diff --git a/versioned_docs/version-2.x/screen-tracking.md b/versioned_docs/version-2.x/screen-tracking.md
index 4bcd02e4626..8ef4aad1470 100644
--- a/versioned_docs/version-2.x/screen-tracking.md
+++ b/versioned_docs/version-2.x/screen-tracking.md
@@ -57,24 +57,27 @@ import { GoogleAnalyticsTracker } from 'react-native-google-analytics-bridge';
const tracker = new GoogleAnalyticsTracker(GA_TRACKING_ID);
-const screenTracking = ({ getState }) => next => (action) => {
- if (
- action.type !== NavigationActions.NAVIGATE
- && action.type !== NavigationActions.BACK
- ) {
- return next(action);
- }
-
- const currentScreen = getActiveRouteName(getState().navigation);
- const result = next(action);
- const nextScreen = getActiveRouteName(getState().navigation);
- if (nextScreen !== currentScreen) {
- // the line below uses the Google Analytics tracker
- // change the tracker here to use other Mobile analytics SDK.
- tracker.trackScreenView(nextScreen);
- }
- return result;
-};
+const screenTracking =
+ ({ getState }) =>
+ (next) =>
+ (action) => {
+ if (
+ action.type !== NavigationActions.NAVIGATE &&
+ action.type !== NavigationActions.BACK
+ ) {
+ return next(action);
+ }
+
+ const currentScreen = getActiveRouteName(getState().navigation);
+ const result = next(action);
+ const nextScreen = getActiveRouteName(getState().navigation);
+ if (nextScreen !== currentScreen) {
+ // the line below uses the Google Analytics tracker
+ // change the tracker here to use other Mobile analytics SDK.
+ tracker.trackScreenView(nextScreen);
+ }
+ return result;
+ };
export default screenTracking;
```
diff --git a/versioned_docs/version-2.x/stack-actions.md b/versioned_docs/version-2.x/stack-actions.md
index cdf48afae9b..bad6b5d5db1 100644
--- a/versioned_docs/version-2.x/stack-actions.md
+++ b/versioned_docs/version-2.x/stack-actions.md
@@ -8,19 +8,19 @@ sidebar_label: StackActions
The following actions are supported:
-* [Reset](#reset) - Replace current state with a new state
-* [Replace](#replace) - Replace a route at a given key with another route
-* [Push](#push) - Add a route on the top of the stack, and navigate forward to it
-* [Pop](#pop) - Navigate back to previous routes
-* [PopToTop](#poptotop) - Navigate to the top route of the stack, dismissing all other routes
+- [Reset](#reset) - Replace current state with a new state
+- [Replace](#replace) - Replace a route at a given key with another route
+- [Push](#push) - Add a route on the top of the stack, and navigate forward to it
+- [Pop](#pop) - Navigate back to previous routes
+- [PopToTop](#poptotop) - Navigate to the top route of the stack, dismissing all other routes
### reset
The `reset` action wipes the whole navigation state and replaces it with the result of several actions.
-* `index` - _number_ - required - Index of the active route on `routes` array in navigation `state`.
-* `actions` - _array_ - required - Array of Navigation Actions that will replace the navigation state.
-* `key` - _string or null_ - optional - If set, the navigator with the given key will reset. If null, the root navigator will reset.
+- `index` - _number_ - required - Index of the active route on `routes` array in navigation `state`.
+- `actions` - _array_ - required - Array of Navigation Actions that will replace the navigation state.
+- `key` - _string or null_ - optional - If set, the navigator with the given key will reset. If null, the root navigator will reset.
```js
import { StackActions, NavigationActions } from 'react-navigation';
@@ -56,20 +56,20 @@ this.props.navigation.dispatch(resetAction);
The `replace` action replaces the route at the given key with another route.
-* `key` - _string_ - Key of the route to replace. If this is not defined, the most recent route will be replaced.
-* `newKey` - _string_ - Key to use for the replacement route. Generated automatically if not provided.
-* `routeName` - _string_ - `routeName` to use for replacement route.
-* `params` - _object_ - Parameters to pass in to the replacement route.
-* `action` - _object_ - Optional sub-action.
-* `immediate`*- _boolean_ -*Currently has no effect, this is a placeholder for when stack navigator supports animated replace (it currently does not).
+- `key` - _string_ - Key of the route to replace. If this is not defined, the most recent route will be replaced.
+- `newKey` - _string_ - Key to use for the replacement route. Generated automatically if not provided.
+- `routeName` - _string_ - `routeName` to use for replacement route.
+- `params` - _object_ - Parameters to pass in to the replacement route.
+- `action` - _object_ - Optional sub-action.
+- `immediate`*- *boolean* -*Currently has no effect, this is a placeholder for when stack navigator supports animated replace (it currently does not).
### push
The `push` action adds a route on top of the stack and navigates forward to it. This differs from `navigate` in that `navigate` will pop back to earlier in the stack if a route of the given name is already present there. `push` will always add on top, so a route can be present multiple times.
-* `routeName` - _string_ - `routeName` to push onto the stack.
-* `params` - _object_ - Screen params to merge into the destination route (found in the pushed screen through `this.props.navigation.state.params`).
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator.
+- `routeName` - _string_ - `routeName` to push onto the stack.
+- `params` - _object_ - Screen params to merge into the destination route (found in the pushed screen through `this.props.navigation.state.params`).
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator.
```js
import { StackActions } from 'react-navigation';
@@ -88,7 +88,7 @@ this.props.navigation.dispatch(pushAction);
The `pop` action takes you back to a previous screen in the stack. The `n` param allows you to specify how many screens to pop back by.
-* `n` - _number_ - The number of screens to pop back by.
+- `n` - _number_ - The number of screens to pop back by.
```js
import { StackActions } from 'react-navigation';
diff --git a/versioned_docs/version-2.x/stack-navigator.md b/versioned_docs/version-2.x/stack-navigator.md
index 261c9752935..25485fb19b7 100644
--- a/versioned_docs/version-2.x/stack-navigator.md
+++ b/versioned_docs/version-2.x/stack-navigator.md
@@ -44,37 +44,37 @@ createStackNavigator({
Options for the router:
-* `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
-* `initialRouteParams` - The params for the initial route
-* `initialRouteKey` - Optional identifier of the initial route
-* `navigationOptions` - Default navigation options to use for screens
-* `paths` - A mapping of overrides for the paths set in the route configs
-* `disableKeyboardHandling` - If true, the keyboard will NOT automatically dismiss when navigating to a new screen. Defaults to false. This is ignored in the web platform.
+- `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
+- `initialRouteParams` - The params for the initial route
+- `initialRouteKey` - Optional identifier of the initial route
+- `navigationOptions` - Default navigation options to use for screens
+- `paths` - A mapping of overrides for the paths set in the route configs
+- `disableKeyboardHandling` - If true, the keyboard will NOT automatically dismiss when navigating to a new screen. Defaults to false. This is ignored in the web platform.
Visual options:
-* `mode` - Defines the style for rendering and transitions:
- * `card` - Use the standard iOS and Android screen transitions. This is the default.
- * `modal` - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
-* `headerMode` - Specifies how the header should be rendered:
- * `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
- * `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
- * `none` - No header will be rendered.
-* `headerBackTitleVisible` - A reasonable default is supplied for whether the back button title should be visible or not, but if you want to override that you can use `true` or `false` in this option.
-* `headerTransitionPreset` - Specifies how the header should transition from one screen to another when `headerMode: float` is enabled.
- * `fade-in-place` - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
- * `uikit` - An approximation of the default behavior for iOS.
-* `headerLayoutPreset` - Specifies how to lay out the header components.
- * `left` - Anchor the title to the left, near the back button or other left component. This is the default on Android. When used on iOS, the header back title is hidden. Content from the left component will overflow underneath the title, if you need to adjust this you can use `headerLeftContainerStyle` and `headerTitleContainerStyle`. Additionally, this alignment is incompatible with `headerTransitionPreset: 'uikit'`.
- * `center` - Center the title, this is the default on iOS.
-* `cardStyle` - Use this prop to override or extend the default style for an individual card in stack.
-* `transitionConfig` - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](https://github.com/react-navigation/react-navigation/blob/2.x/flow/react-navigation.js)). Provided function will be passed the following arguments:
- * `transitionProps` - Transition props for the new screen.
- * `prevTransitionProps` - Transitions props for the old screen.
- * `isModal` - Boolean specifying if screen is modal.
-* `onTransitionStart` - Function to be invoked when the card transition animation is about to start.
-* `onTransitionEnd` - Function to be invoked once the card transition animation completes.
-* `transparentCard` - *Experimental* - Prop to keep all cards in the stack visible and add a transparent background instead of a white one. This is useful to implement things like modal dialogs where the previous scene should still be visible underneath the current one.
+- `mode` - Defines the style for rendering and transitions:
+ - `card` - Use the standard iOS and Android screen transitions. This is the default.
+ - `modal` - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
+- `headerMode` - Specifies how the header should be rendered:
+ - `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
+ - `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
+ - `none` - No header will be rendered.
+- `headerBackTitleVisible` - A reasonable default is supplied for whether the back button title should be visible or not, but if you want to override that you can use `true` or `false` in this option.
+- `headerTransitionPreset` - Specifies how the header should transition from one screen to another when `headerMode: float` is enabled.
+ - `fade-in-place` - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
+ - `uikit` - An approximation of the default behavior for iOS.
+- `headerLayoutPreset` - Specifies how to lay out the header components.
+ - `left` - Anchor the title to the left, near the back button or other left component. This is the default on Android. When used on iOS, the header back title is hidden. Content from the left component will overflow underneath the title, if you need to adjust this you can use `headerLeftContainerStyle` and `headerTitleContainerStyle`. Additionally, this alignment is incompatible with `headerTransitionPreset: 'uikit'`.
+ - `center` - Center the title, this is the default on iOS.
+- `cardStyle` - Use this prop to override or extend the default style for an individual card in stack.
+- `transitionConfig` - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](https://github.com/react-navigation/react-navigation/blob/2.x/flow/react-navigation.js)). Provided function will be passed the following arguments:
+ - `transitionProps` - Transition props for the new screen.
+ - `prevTransitionProps` - Transitions props for the old screen.
+ - `isModal` - Boolean specifying if screen is modal.
+- `onTransitionStart` - Function to be invoked when the card transition animation is about to start.
+- `onTransitionEnd` - Function to be invoked once the card transition animation completes.
+- `transparentCard` - _Experimental_ - Prop to keep all cards in the stack visible and add a transparent background instead of a white one. This is useful to implement things like modal dialogs where the previous scene should still be visible underneath the current one.
### `navigationOptions` for screens inside of the navigator
@@ -108,7 +108,7 @@ StackNavigator({
screen: AScreen,
navigationOptions: () => ({
title: `A`,
- headerBackTitle: null
+ headerBackTitle: null,
}),
},
B: {
@@ -116,7 +116,7 @@ StackNavigator({
navigationOptions: () => ({
title: `B`,
}),
- }
+ },
});
```
@@ -131,7 +131,7 @@ StackNavigator({
navigationOptions: () => ({
title: `A`,
headerBackTitle: 'A much too long text for back button from B to A',
- headerTruncatedBackTitle: `to A`
+ headerTruncatedBackTitle: `to A`,
}),
},
B: {
@@ -139,7 +139,7 @@ StackNavigator({
navigationOptions: () => ({
title: `B`,
}),
- }
+ },
});
```
@@ -203,8 +203,8 @@ Whether you can use gestures to dismiss this screen. Defaults to true on iOS, fa
Object to override the distance of touch start from the edge of the screen to recognize gestures. It takes the following properties:
-* `horizontal` - *number* - Distance for horizontal direction. Defaults to 25.
-* `vertical` - *number* - Distance for vertical direction. Defaults to 135.
+- `horizontal` - _number_ - Distance for horizontal direction. Defaults to 25.
+- `vertical` - _number_ - Distance for vertical direction. Defaults to 135.
#### `gestureDirection`
@@ -214,7 +214,7 @@ String to override the direction for dismiss gesture. `default` for normal behav
The navigator component created by `StackNavigator(...)` takes the following props:
-* `screenProps` - Pass down extra options to child screens, for example:
+- `screenProps` - Pass down extra options to child screens, for example:
```js
const SomeStack = createStackNavigator({
@@ -252,7 +252,7 @@ const ModalNavigator = createStackNavigator(
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
- screenInterpolator: sceneProps => {
+ screenInterpolator: (sceneProps) => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
@@ -281,17 +281,21 @@ Header transitions can also be configured using `headerLeftInterpolator`, `heade
We can't set the `StackNavigatorConfig`'s `mode` dynamically. Instead we are going to use a custom `transitionConfig` to render the specific transition we want - modal or card - on a screen by screen basis.
```js
-import { createStackNavigator, StackViewTransitionConfigs } from 'react-navigation';
+import {
+ createStackNavigator,
+ StackViewTransitionConfigs,
+} from 'react-navigation';
/* The screens you add to IOS_MODAL_ROUTES will have the modal transition. */
const IOS_MODAL_ROUTES = ['OptionsScreen'];
let dynamicModalTransition = (transitionProps, prevTransitionProps) => {
const isModal = IOS_MODAL_ROUTES.some(
- screenName =>
+ (screenName) =>
screenName === transitionProps.scene.route.routeName ||
- (prevTransitionProps && screenName === prevTransitionProps.scene.route.routeName)
- )
+ (prevTransitionProps &&
+ screenName === prevTransitionProps.scene.route.routeName)
+ );
return StackViewTransitionConfigs.defaultTransitionConfig(
transitionProps,
prevTransitionProps,
diff --git a/versioned_docs/version-2.x/status-bar.md b/versioned_docs/version-2.x/status-bar.md
index fec25b0ccc0..a3edd8e52ca 100644
--- a/versioned_docs/version-2.x/status-bar.md
+++ b/versioned_docs/version-2.x/status-bar.md
@@ -15,17 +15,12 @@ class Screen1 extends React.Component {
render() {
return (
-
-
- Light Screen
-
+
+ Light Screen
this.props.navigation.navigate('Screen2')}
- color={isAndroid ? "blue" : "#fff"}
+ color={isAndroid ? 'blue' : '#fff'}
/>
);
@@ -36,13 +31,8 @@ class Screen2 extends React.Component {
render() {
return (
-
-
- Dark Screen
-
+
+ Dark Screen
this.props.navigation.navigate('Screen1')}
@@ -54,16 +44,19 @@ class Screen2 extends React.Component {
```
```javascript
-export default createStackNavigator({
- Screen1: {
- screen: Screen1,
+export default createStackNavigator(
+ {
+ Screen1: {
+ screen: Screen1,
+ },
+ Screen2: {
+ screen: Screen2,
+ },
},
- Screen2: {
- screen: Screen2,
- },
-}, {
- headerMode: 'none',
-});
+ {
+ headerMode: 'none',
+ }
+);
```

@@ -97,9 +90,7 @@ class Screen2 extends React.Component {
render() {
return (
-
- Dark Screen
-
+ Dark Screen
this.props.navigation.navigate('Screen1')}
diff --git a/versioned_docs/version-2.x/tab-based-navigation.md b/versioned_docs/version-2.x/tab-based-navigation.md
index e6b3eb4c96e..5276ed73bf9 100644
--- a/versioned_docs/version-2.x/tab-based-navigation.md
+++ b/versioned_docs/version-2.x/tab-based-navigation.md
@@ -71,7 +71,13 @@ export default createBottomTabNavigator(
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
- return ;
+ return (
+
+ );
},
}),
tabBarOptions: {
@@ -86,9 +92,9 @@ export default createBottomTabNavigator(
Let's dissect this:
-* `tabBarIcon` is a property on `navigationOptions`, so we know we can use it on our screen components, but in this case chose to put it in the `createBottomTabNavigator` configuration in order to centralize the icon configuration for convenience.
-* `tabBarIcon` is a function that is given the `focused` state, `tintColor`, and `horizontal` param, which is a boolean. If you take a peek further down in the configuration you will see `tabBarOptions` and `activeTintColor` and `inactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `tintColor` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active). The orientation state `horizontal` is `true` when the device is in landscape, otherwise is `false` for portrait.
-* Read the [full API reference](bottom-tab-navigator.md) for further information on `createBottomTabNavigator` configuration options.
+- `tabBarIcon` is a property on `navigationOptions`, so we know we can use it on our screen components, but in this case chose to put it in the `createBottomTabNavigator` configuration in order to centralize the icon configuration for convenience.
+- `tabBarIcon` is a function that is given the `focused` state, `tintColor`, and `horizontal` param, which is a boolean. If you take a peek further down in the configuration you will see `tabBarOptions` and `activeTintColor` and `inactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `tintColor` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active). The orientation state `horizontal` is `true` when the device is in landscape, otherwise is `false` for portrait.
+- Read the [full API reference](bottom-tab-navigator.md) for further information on `createBottomTabNavigator` configuration options.
## Jumping between tabs
diff --git a/versioned_docs/version-2.x/tab-navigator.md b/versioned_docs/version-2.x/tab-navigator.md
index fb726873657..196e13b97a1 100644
--- a/versioned_docs/version-2.x/tab-navigator.md
+++ b/versioned_docs/version-2.x/tab-navigator.md
@@ -16,34 +16,34 @@ The route configs object is a mapping from route name to a route config, which t
## TabNavigatorConfig
-* `tabBarComponent` - Component to use as the tab bar, e.g. `TabBarBottom` (this is the default on iOS), `TabBarTop` (this is the default on Android).
-* `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`.
-* `swipeEnabled` - Whether to allow swiping between tabs.
-* `animationEnabled` - Whether to animate when changing tabs.
-* `lazy` - Defaults to `true`. If `false`, all tabs are rendered immediately. When `true`, tabs are rendered only when they are made active.
-* `removeClippedSubviews` - Defaults to `true`. An optimization to reduce memory usage by freeing resources used by inactive tabs.
-* `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view#avoid-one-frame-delay) rendering.
-* `tabBarOptions` - Configure the tab bar, see below.
+- `tabBarComponent` - Component to use as the tab bar, e.g. `TabBarBottom` (this is the default on iOS), `TabBarTop` (this is the default on Android).
+- `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`.
+- `swipeEnabled` - Whether to allow swiping between tabs.
+- `animationEnabled` - Whether to animate when changing tabs.
+- `lazy` - Defaults to `true`. If `false`, all tabs are rendered immediately. When `true`, tabs are rendered only when they are made active.
+- `removeClippedSubviews` - Defaults to `true`. An optimization to reduce memory usage by freeing resources used by inactive tabs.
+- `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view#avoid-one-frame-delay) rendering.
+- `tabBarOptions` - Configure the tab bar, see below.
Several options get passed to the underlying router to modify navigation logic:
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - Should the back button cause a tab switch to the initial tab? If yes, set to `initialRoute`, otherwise `none`. Defaults to `initialRoute` behavior.
### `tabBarOptions` for `TabBarBottom` (default tab bar on iOS)
-* `activeTintColor` - Label and icon color of the active tab.
-* `activeBackgroundColor` - Background color of the active tab.
-* `inactiveTintColor` - Label and icon color of the inactive tab.
-* `inactiveBackgroundColor` - Background color of the inactive tab.
-* `showLabel` - Whether to show label for tab, default is true.
-* `style` - Style object for the tab bar.
-* `labelStyle` - Style object for the tab label.
-* `tabStyle` - Style object for the tab.
-* `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
-* `safeAreaInset` - Override the `forceInset` prop for ``. Defaults to `{ bottom: 'always', top: 'never' }`. Available keys are `top | bottom | left | right` provided with the values `'always' | 'never'`.
+- `activeTintColor` - Label and icon color of the active tab.
+- `activeBackgroundColor` - Background color of the active tab.
+- `inactiveTintColor` - Label and icon color of the inactive tab.
+- `inactiveBackgroundColor` - Background color of the inactive tab.
+- `showLabel` - Whether to show label for tab, default is true.
+- `style` - Style object for the tab bar.
+- `labelStyle` - Style object for the tab label.
+- `tabStyle` - Style object for the tab.
+- `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
+- `safeAreaInset` - Override the `forceInset` prop for ``. Defaults to `{ bottom: 'always', top: 'never' }`. Available keys are `top | bottom | left | right` provided with the values `'always' | 'never'`.
Example:
@@ -61,20 +61,20 @@ tabBarOptions: {
### `tabBarOptions` for `TabBarTop` (default tab bar on Android)
-* `activeTintColor` - Label and icon color of the active tab.
-* `inactiveTintColor` - Label and icon color of the inactive tab.
-* `showIcon` - Whether to show icon for tab, default is false.
-* `showLabel` - Whether to show label for tab, default is true.
-* `upperCaseLabel` - Whether to make label uppercase, default is true.
-* `pressColor` - Color for material ripple (Android >= 5.0 only).
-* `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
-* `scrollEnabled` - Whether to enable scrollable tabs.
-* `tabStyle` - Style object for the tab.
-* `indicatorStyle` - Style object for the tab indicator (line at the bottom of the tab).
-* `labelStyle` - Style object for the tab label.
-* `iconStyle` - Style object for the tab icon.
-* `style` - Style object for the tab bar.
-* `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
+- `activeTintColor` - Label and icon color of the active tab.
+- `inactiveTintColor` - Label and icon color of the inactive tab.
+- `showIcon` - Whether to show icon for tab, default is false.
+- `showLabel` - Whether to show label for tab, default is true.
+- `upperCaseLabel` - Whether to make label uppercase, default is true.
+- `pressColor` - Color for material ripple (Android >= 5.0 only).
+- `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
+- `scrollEnabled` - Whether to enable scrollable tabs.
+- `tabStyle` - Style object for the tab.
+- `indicatorStyle` - Style object for the tab indicator (line at the bottom of the tab).
+- `labelStyle` - Style object for the tab label.
+- `iconStyle` - Style object for the tab icon.
+- `style` - Style object for the tab bar.
+- `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
Example:
@@ -118,8 +118,8 @@ Title string of a tab displayed in the tab bar or React Element or a function th
Callback to handle tap events; the argument is an object containing:
-* the `previousScene: { route, index }` which is the scene we are leaving
-* the `scene: { route, index }` that was tapped
-* the `jumpToIndex` method that can perform the navigation for you
+- the `previousScene: { route, index }` which is the scene we are leaving
+- the `scene: { route, index }` that was tapped
+- the `jumpToIndex` method that can perform the navigation for you
Useful for adding a custom logic before the transition to the next scene (the tapped one) starts.
diff --git a/versioned_docs/version-2.x/with-navigation-focus.md b/versioned_docs/version-2.x/with-navigation-focus.md
index 8ab8d51e0ce..a8d73142585 100644
--- a/versioned_docs/version-2.x/with-navigation-focus.md
+++ b/versioned_docs/version-2.x/with-navigation-focus.md
@@ -6,7 +6,7 @@ sidebar_label: withNavigationFocus
`withNavigationFocus` is a higher order component which passes the `isFocused` prop into a wrapped component. It's useful if you need to use the focus state in the render function of your screen component or another component rendered somewhere inside of a screen.
-* `withNavigationFocus(Component)` returns a component.
+- `withNavigationFocus(Component)` returns a component.
## Example
diff --git a/versioned_docs/version-2.x/with-navigation.md b/versioned_docs/version-2.x/with-navigation.md
index 93c931e668b..3bfcfd8e421 100644
--- a/versioned_docs/version-2.x/with-navigation.md
+++ b/versioned_docs/version-2.x/with-navigation.md
@@ -17,7 +17,14 @@ import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
diff --git a/versioned_docs/version-3.x/MST-integration.md b/versioned_docs/version-3.x/MST-integration.md
index 2ce8a8755f6..93e55fac08e 100644
--- a/versioned_docs/version-3.x/MST-integration.md
+++ b/versioned_docs/version-3.x/MST-integration.md
@@ -61,7 +61,7 @@ export const NavigationStore = types
}));
```
-Note that `userProfileScreenParams` is a simple model with a `user` entry, while `productDetailScreenParams` is a map of `ProductDetailScreenParams` model. The reason we chose this shape of data is that we only have a single user profile screen in our app which reads its params from `userProfileScreenParams`. `productDetailScreenParams` is a map because the app can have several product screens on a stack. Each screen points to a `Product` instance saved in the map. The keys into the map are the React Navigation [keys](navigation-key.md#usage-with-the-navigate-navigation-actionshtml-navigate-call): think of the `key` as of an identifier of the route.
+Note that `userProfileScreenParams` is a simple model with a `user` entry, while `productDetailScreenParams` is a map of `ProductDetailScreenParams` model. The reason we chose this shape of data is that we only have a single user profile screen in our app which reads its params from `userProfileScreenParams`. `productDetailScreenParams` is a map because the app can have several product screens on a stack. Each screen points to a `Product` instance saved in the map. The keys into the map are the React Navigation [keys](navigation-key.md#usage-with-the-navigate-call): think of the `key` as of an identifier of the route.
Your navigation store may also be just one map where for each screen (regardless if it is a product or user profile screen), we store its navigation params. This is the approach taken in the [sample app](https://github.com/vonovak/react-navigation-mst-demo).
diff --git a/versioned_docs/version-3.x/app-containers.md b/versioned_docs/version-3.x/app-containers.md
index 5fe4d7e6265..6710ea80f2e 100644
--- a/versioned_docs/version-3.x/app-containers.md
+++ b/versioned_docs/version-3.x/app-containers.md
@@ -58,7 +58,7 @@ class App extends React.Component {
render() {
return (
{
+ ref={(nav) => {
this.navigator = nav;
}}
/>
diff --git a/versioned_docs/version-3.x/auth-flow.md b/versioned_docs/version-3.x/auth-flow.md
index 53901e76296..c8fadc1a443 100644
--- a/versioned_docs/version-3.x/auth-flow.md
+++ b/versioned_docs/version-3.x/auth-flow.md
@@ -6,17 +6,21 @@ sidebar_label: Authentication flows
Most apps require that a user authenticate in some way to have access to data associated with a user or other private content. Typically the flow will look like this:
-* The user opens the app.
-* The app loads some authentication state from persistent storage (for example, `AsyncStorage`).
-* When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
-* When the user signs out, we clear the authentication state and send them back to authentication screens.
+- The user opens the app.
+- The app loads some authentication state from persistent storage (for example, `AsyncStorage`).
+- When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
+- When the user signs out, we clear the authentication state and send them back to authentication screens.
> Note: we say "authentication screens" because usually there is more than one. You may have a main screen with a username and password field, another for "forgot password", and another set for sign up.
## Set up our navigators
```js
-import { createSwitchNavigator, createStackNavigator, createAppContainer } from 'react-navigation';
+import {
+ createSwitchNavigator,
+ createStackNavigator,
+ createAppContainer,
+} from 'react-navigation';
// Implementation of HomeScreen, OtherScreen, SignInScreen, AuthLoadingScreen
// goes here.
@@ -24,16 +28,18 @@ import { createSwitchNavigator, createStackNavigator, createAppContainer } from
const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
-export default createAppContainer(createSwitchNavigator(
- {
- AuthLoading: AuthLoadingScreen,
- App: AppStack,
- Auth: AuthStack,
- },
- {
- initialRouteName: 'AuthLoading',
- }
-));
+export default createAppContainer(
+ createSwitchNavigator(
+ {
+ AuthLoading: AuthLoadingScreen,
+ App: AppStack,
+ Auth: AuthStack,
+ },
+ {
+ initialRouteName: 'AuthLoading',
+ }
+ )
+);
```
→ Run this code
diff --git a/versioned_docs/version-3.x/bottom-tab-navigator.md b/versioned_docs/version-3.x/bottom-tab-navigator.md
index 6061c0efe02..5d2d5ea3d01 100644
--- a/versioned_docs/version-3.x/bottom-tab-navigator.md
+++ b/versioned_docs/version-3.x/bottom-tab-navigator.md
@@ -18,29 +18,29 @@ The route configs object is a mapping from route name to a route config, which t
## BottomTabNavigatorConfig
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `navigationOptions` - Navigation options for the navigator itself, to configure a parent navigator
-* `defaultNavigationOptions` - Default navigation options to use for screens
-* `resetOnBlur` - Reset the state of any nested navigators when switching away from a screen. Defaults to `false`.
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - `initialRoute` to return to initial tab, `order` to return to previous tab, `history` to return to last visited tab, or `none`.
-* `lazy` - Defaults to `true`. If `false`, all tabs are rendered immediately. When `true`, tabs are rendered only when they are made active for the first time. Note: tabs are **not** re-rendered upon subsequent visits.
-* `tabBarComponent` - Optional, override component to use as the tab bar.
-* `tabBarOptions` - An object with the following properties:
- * `activeTintColor` - Label and icon color of the active tab.
- * `activeBackgroundColor` - Background color of the active tab.
- * `inactiveTintColor` - Label and icon color of the inactive tab.
- * `inactiveBackgroundColor` - Background color of the inactive tab.
- * `showLabel` - Whether to show label for tab, default is true.
- * `showIcon` - Whether to show icon for tab, default is true.
- * `style` - Style object for the tab bar.
- * `labelStyle` - Style object for the tab label.
- * `tabStyle` - Style object for the tab.
- * `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
- * `adaptive` - Should the tab icons and labels alignment change based on screen size? Defaults to `true` for iOS 11. If `false`, tab icons and labels align vertically all the time. When `true`, tab icons and labels align horizontally on tablet.
- * `safeAreaInset` - Override the `forceInset` prop for ``. Defaults to `{ bottom: 'always', top: 'never' }`. Available keys are `top | bottom | left | right` provided with the values `'always' | 'never'`.
- * `keyboardHidesTabBar` - Defaults to `false`. If `true` hide the tab bar when keyboard opens.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `navigationOptions` - Navigation options for the navigator itself, to configure a parent navigator
+- `defaultNavigationOptions` - Default navigation options to use for screens
+- `resetOnBlur` - Reset the state of any nested navigators when switching away from a screen. Defaults to `false`.
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - `initialRoute` to return to initial tab, `order` to return to previous tab, `history` to return to last visited tab, or `none`.
+- `lazy` - Defaults to `true`. If `false`, all tabs are rendered immediately. When `true`, tabs are rendered only when they are made active for the first time. Note: tabs are **not** re-rendered upon subsequent visits.
+- `tabBarComponent` - Optional, override component to use as the tab bar.
+- `tabBarOptions` - An object with the following properties:
+ - `activeTintColor` - Label and icon color of the active tab.
+ - `activeBackgroundColor` - Background color of the active tab.
+ - `inactiveTintColor` - Label and icon color of the inactive tab.
+ - `inactiveBackgroundColor` - Background color of the inactive tab.
+ - `showLabel` - Whether to show label for tab, default is true.
+ - `showIcon` - Whether to show icon for tab, default is true.
+ - `style` - Style object for the tab bar.
+ - `labelStyle` - Style object for the tab label.
+ - `tabStyle` - Style object for the tab.
+ - `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
+ - `adaptive` - Should the tab icons and labels alignment change based on screen size? Defaults to `true` for iOS 11. If `false`, tab icons and labels align vertically all the time. When `true`, tab icons and labels align horizontally on tablet.
+ - `safeAreaInset` - Override the `forceInset` prop for ``. Defaults to `{ bottom: 'always', top: 'never' }`. Available keys are `top | bottom | left | right` provided with the values `'always' | 'never'`.
+ - `keyboardHidesTabBar` - Defaults to `false`. If `true` hide the tab bar when keyboard opens.
Example:
@@ -61,17 +61,13 @@ If you want to customize the `tabBarComponent`:
```js
import { createBottomTabNavigator, BottomTabBar } from 'react-navigation-tabs';
-const TabBarComponent = (props) => ( );
+const TabBarComponent = (props) => ;
-const TabScreens = createBottomTabNavigator(
- {
- tabBarComponent: props =>
- ,
- },
-);
+const TabScreens = createBottomTabNavigator({
+ tabBarComponent: (props) => (
+
+ ),
+});
```
## `navigationOptions` for screens inside of the navigator
@@ -108,8 +104,8 @@ ID to locate this tab button in tests.
Callback to handle press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
Useful for adding a custom logic before the transition to the next scene (the
tapped one) starts.
@@ -120,5 +116,5 @@ Define this callback without ever invoking `defaultHandler` to prevent any navig
Callback to handle long press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
diff --git a/versioned_docs/version-3.x/common-mistakes.md b/versioned_docs/version-3.x/common-mistakes.md
index b2cffa235a2..b470d32fa95 100644
--- a/versioned_docs/version-3.x/common-mistakes.md
+++ b/versioned_docs/version-3.x/common-mistakes.md
@@ -34,9 +34,7 @@ class AuthenticationScreen extends React.Component {
* You should avoid this! It will have its own navigation state and be unable
* To interact with any parent navigator, eg: it would not know the route "Home" exists
*/
- return (
-
- );
+ return ;
}
}
@@ -45,7 +43,7 @@ const AppNavigator = createSwitchNavigator({
Home: HomeScreen,
});
-const AppContainer = createAppContainer(AppNavigator)
+const AppContainer = createAppContainer(AppNavigator);
```
The correct way to write this would be the following:
@@ -93,9 +91,7 @@ class AuthenticationScreen extends React.Component {
static router = AuthenticationNavigator.router;
render() {
- return (
-
- );
+ return ;
}
}
@@ -113,13 +109,13 @@ In previous version of React Navigation, the library used to dig through your co
## Wrapping AppContainer in a View without flex
- If you wrap the `AppContainer` in a `View`, make sure the `View` is using flex.
+If you wrap the `AppContainer` in a `View`, make sure the `View` is using flex.
```javascript
import React from 'react';
import { Text, View } from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
- class HomeScreen extends React.Component {
+class HomeScreen extends React.Component {
render() {
return (
@@ -128,7 +124,7 @@ import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
);
}
}
- class SettingsScreen extends React.Component {
+class SettingsScreen extends React.Component {
render() {
return (
@@ -137,11 +133,15 @@ import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
);
}
}
- const TabNavigator = createBottomTabNavigator({
+const TabNavigator = createBottomTabNavigator({
Home: HomeScreen,
Settings: SettingsScreen,
});
- const AppContainer = createAppContainer(TabNavigator)
- // without the style you will see a blank screen
-export default ()=> ;
+const AppContainer = createAppContainer(TabNavigator);
+// without the style you will see a blank screen
+export default () => (
+
+
+
+);
```
diff --git a/versioned_docs/version-3.x/connecting-navigation-prop.md b/versioned_docs/version-3.x/connecting-navigation-prop.md
index 7f24246a255..4dae362c806 100644
--- a/versioned_docs/version-3.x/connecting-navigation-prop.md
+++ b/versioned_docs/version-3.x/connecting-navigation-prop.md
@@ -14,7 +14,14 @@ export default class MyBackButton extends React.Component {
render() {
// This will throw an 'undefined is not a function' exception because the navigation
// prop is undefined.
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
```
@@ -30,7 +37,14 @@ import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
diff --git a/versioned_docs/version-3.x/custom-android-back-button-handling.md b/versioned_docs/version-3.x/custom-android-back-button-handling.md
index 10b48240c14..0b5f3beb7de 100644
--- a/versioned_docs/version-3.x/custom-android-back-button-handling.md
+++ b/versioned_docs/version-3.x/custom-android-back-button-handling.md
@@ -8,7 +8,7 @@ By default, when user presses the Android hardware back button, react-navigation
> If you're looking for an easy-to-use solution, you can check out a community-developed package [react-navigation-backhandler](https://github.com/vonovak/react-navigation-backhandler). The following text shows what the package does under the cover.
-As an example, consider a screen where user is selecting items in a list, and a "selection mode" is active. On a back button press, you would first want the "selection mode" to be deactivated, and the screen should be popped only on the second back button press. The following code snippet demonstrates the situation. We make use of [`BackHandler`](https://reactnative.dev/docs/backhandler.html) which comes with react-native and we [subscribe to navigation lifecycle updates](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle) to add our custom `hardwareBackPress` listener.
+As an example, consider a screen where user is selecting items in a list, and a "selection mode" is active. On a back button press, you would first want the "selection mode" to be deactivated, and the screen should be popped only on the second back button press. The following code snippet demonstrates the situation. We make use of [`BackHandler`](https://reactnative.dev/docs/backhandler.html) which comes with react-native and we [subscribe to navigation lifecycle updates](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle) to add our custom `hardwareBackPress` listener.
Returning `true` from `onBackButtonPressAndroid` denotes that we have handled the event, and react-navigation's listener will not get called, thus not popping the screen. Returning `false` will cause the event to bubble up and react-navigation's listener will pop the screen.
diff --git a/versioned_docs/version-3.x/custom-navigator-overview.md b/versioned_docs/version-3.x/custom-navigator-overview.md
index 97826743dd7..39699c3bda9 100644
--- a/versioned_docs/version-3.x/custom-navigator-overview.md
+++ b/versioned_docs/version-3.x/custom-navigator-overview.md
@@ -24,4 +24,4 @@ The navigators render application screens which are just React components.
To learn how to create screens, read about:
- [Screen `navigation` prop](navigation-prop.md) to allow the screen to dispatch navigation actions, such as opening another screen
-- Screen `navigationOptions` to customize how the screen gets presented by the navigator (e.g. [header title](stack-navigator.md#navigationoptions-used-by-stacknavigator), tab label)
+- Screen `navigationOptions` to customize how the screen gets presented by the navigator (e.g. [header title](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator), tab label)
diff --git a/versioned_docs/version-3.x/custom-navigators.md b/versioned_docs/version-3.x/custom-navigators.md
index c9c473e5ab2..5703b0e6a4e 100644
--- a/versioned_docs/version-3.x/custom-navigators.md
+++ b/versioned_docs/version-3.x/custom-navigators.md
@@ -101,7 +101,7 @@ To help developers implement custom navigators, the following utilities are prov
This utility combines a [router](routers.md) and a [navigation view](navigation-views.md) together in a standard way:
```js
-import { createNavigator } from "react-navigation";
+import { createNavigator } from 'react-navigation';
const AppNavigator = createNavigator(NavigationView, router, navigationConfig);
```
diff --git a/versioned_docs/version-3.x/deep-linking.md b/versioned_docs/version-3.x/deep-linking.md
index 7adc9312c4d..cce7c6f89bf 100644
--- a/versioned_docs/version-3.x/deep-linking.md
+++ b/versioned_docs/version-3.x/deep-linking.md
@@ -4,7 +4,7 @@ title: Deep linking
sidebar_label: Deep linking
---
-In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `mychat://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
+In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `example://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
## Configuration
@@ -71,7 +71,7 @@ You need to specify a scheme for your app. You can register for a scheme in your
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -125,14 +125,14 @@ Next, let's configure our navigation container to extract the path from the app'
```js
const SimpleApp = createAppContainer(createStackNavigator({...}));
-const prefix = 'mychat://';
+const prefix = 'example://';
const MainApp = () => ;
```
### iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
@@ -151,7 +151,7 @@ In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
In Xcode, open the project at `SimpleApp/ios/SimpleApp.xcodeproj`. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
Now you can press play in Xcode, or re-build on the command line:
@@ -162,10 +162,10 @@ react-native run-ios
To test the URI on the simulator, run the following:
```
-xcrun simctl openurl booted mychat://chat/Eric
+xcrun simctl openurl booted example://chat/Eric
```
-To test the URI on a real device, open Safari and type `mychat://chat/Eric`.
+To test the URI on a real device, open Safari and type `example://chat/Eric`.
### Android
@@ -188,7 +188,7 @@ In `SimpleApp/android/app/src/main/AndroidManifest.xml`, do these followings adj
-
+
```
@@ -202,7 +202,7 @@ react-native run-android
To test the intent handling in Android, run the following:
```
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/Eric" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/Eric" com.simpleapp
```
## Disable deep linking
diff --git a/versioned_docs/version-3.x/drawer-actions.md b/versioned_docs/version-3.x/drawer-actions.md
index b6e23b40109..44f67c73056 100644
--- a/versioned_docs/version-3.x/drawer-actions.md
+++ b/versioned_docs/version-3.x/drawer-actions.md
@@ -8,14 +8,14 @@ sidebar_label: DrawerActions
The following actions are supported:
-* [openDrawer](#openDrawer) - open the drawer
-* [closeDrawer](#closeDrawer) - close the drawer
-* [toggleDrawer](#toggleDrawer) - toggle the state, ie. switch from closed to open and vice versa
+- openDrawer - open the drawer
+- closeDrawer - close the drawer
+- toggleDrawer - toggle the state, ie. switch from closed to open and vice versa
### Usage
```js
import { DrawerActions } from 'react-navigation-drawer';
-this.props.navigation.dispatch(DrawerActions.toggleDrawer())
+this.props.navigation.dispatch(DrawerActions.toggleDrawer());
```
diff --git a/versioned_docs/version-3.x/drawer-based-navigation.md b/versioned_docs/version-3.x/drawer-based-navigation.md
index ceb244e4e12..28c3966f709 100644
--- a/versioned_docs/version-3.x/drawer-based-navigation.md
+++ b/versioned_docs/version-3.x/drawer-based-navigation.md
@@ -3,6 +3,7 @@ id: drawer-based-navigation
title: Drawer navigation
sidebar_label: Drawer navigation
---
+
The drawer navigator allows you to present a navigation menu to your users. It can be customized out of the box, or you can completely control with a custom component.
This guide covers [createDrawerNavigator](drawer-navigator.md).
diff --git a/versioned_docs/version-3.x/drawer-navigator.md b/versioned_docs/version-3.x/drawer-navigator.md
index d928db165b5..9d50054026e 100644
--- a/versioned_docs/version-3.x/drawer-navigator.md
+++ b/versioned_docs/version-3.x/drawer-navigator.md
@@ -44,9 +44,12 @@ The default component for the drawer is scrollable and only contains links for t
```js
import { DrawerItems, SafeAreaView } from 'react-navigation';
-const CustomDrawerContentComponent = props => (
+const CustomDrawerContentComponent = (props) => (
-
+
@@ -62,13 +65,17 @@ const styles = StyleSheet.create({
`contentComponent` also received a prop called `drawerOpenProgress` which is an [animated value](https://reactnative.dev/docs/animated#value) that represents the animated position of the drawer (0 is closed; 1 is open). This allows you to do interesting animations in your `contentComponent`, such as parallax motion of the drawer contents:
```js
-const CustomDrawerContentComponent = props => {
+const CustomDrawerContentComponent = (props) => {
const translateX = props.drawerOpenProgress.interpolate({
inputRange: [0, 1],
outputRange: [-100, 0],
});
- return {/* ... drawer contents */} ;
+ return (
+
+ {/* ... drawer contents */}
+
+ );
};
```
diff --git a/versioned_docs/version-3.x/function-after-focusing-screen.md b/versioned_docs/version-3.x/function-after-focusing-screen.md
index b69c4591aaf..195347f8642 100644
--- a/versioned_docs/version-3.x/function-after-focusing-screen.md
+++ b/versioned_docs/version-3.x/function-after-focusing-screen.md
@@ -24,9 +24,9 @@ For instance, if we are attempting to make an API call on focus to fetch some da
### Example
```js
-import React, { Component } from "react";
-import { View } from "react-native";
-import { withNavigationFocus } from "react-navigation";
+import React, { Component } from 'react';
+import { View } from 'react-native';
+import { withNavigationFocus } from 'react-navigation';
class TabScreen extends Component {
componentDidUpdate(prevProps) {
@@ -57,14 +57,14 @@ With this approach, we will only be able to call an action when the screen focus
### Example
```js
-import React, { Component } from "react";
-import { View } from "react-native";
-import { withNavigation } from "react-navigation";
+import React, { Component } from 'react';
+import { View } from 'react-native';
+import { withNavigation } from 'react-navigation';
class TabScreen extends Component {
componentDidMount() {
const { navigation } = this.props;
- this.focusListener = navigation.addListener("didFocus", () => {
+ this.focusListener = navigation.addListener('didFocus', () => {
// The screen is focused
// Call any action
});
diff --git a/versioned_docs/version-3.x/glossary-of-terms.md b/versioned_docs/version-3.x/glossary-of-terms.md
index 6ef7deeebc3..e36c8a6ffae 100644
--- a/versioned_docs/version-3.x/glossary-of-terms.md
+++ b/versioned_docs/version-3.x/glossary-of-terms.md
@@ -18,7 +18,7 @@ A screen component is a component that we use in our route configuration.
const AppNavigator = createStackNavigator(
{
Home: {
- screen: HomeScreen, // <----
+ screen: HomeScreen, // <----
},
Details: {
screen: DetailsScreen, // <----
@@ -32,7 +32,7 @@ const AppNavigator = createStackNavigator(
The suffix `Screen` in the component name is entirely optional, but a frequently used convention; we could call it `CasaPantalla` and this would work just the same.
-We saw earlier that our screen components are provided with the `navigation` prop. It's important to note that *this only happens if the screen is rendered as a route by React Navigation* (for example, in response to `this.props.navigation.navigate`). For example, if we render `DetailsScreen` as a child of `HomeScreen`, then `DetailsScreen` won't be provided with the `navigation` prop, and when you press the "Go to Details... again" button on the Home screen, the app will throw one of the quintessential JavaScript exceptions "undefined is not an object".
+We saw earlier that our screen components are provided with the `navigation` prop. It's important to note that _this only happens if the screen is rendered as a route by React Navigation_ (for example, in response to `this.props.navigation.navigate`). For example, if we render `DetailsScreen` as a child of `HomeScreen`, then `DetailsScreen` won't be provided with the `navigation` prop, and when you press the "Go to Details... again" button on the Home screen, the app will throw one of the quintessential JavaScript exceptions "undefined is not an object".
```js
class HomeScreen extends React.Component {
diff --git a/versioned_docs/version-3.x/handling-iphonex.md b/versioned_docs/version-3.x/handling-iphonex.md
index a8c8f78c465..dc7e1d36403 100644
--- a/versioned_docs/version-3.x/handling-iphonex.md
+++ b/versioned_docs/version-3.x/handling-iphonex.md
@@ -41,7 +41,7 @@ export default createStackNavigator({
To fix this issue you can wrap your content in a `SafeAreaView`, which can be imported from `react-navigation`. Recall that `SafeAreaView` should not wrap entire navigators, just the screen components or any content in them.
```jsx
-import { SafeAreaView } from 'react-navigation'
+import { SafeAreaView } from 'react-navigation';
class MyHomeScreen extends Component {
render() {
@@ -50,7 +50,7 @@ class MyHomeScreen extends Component {
This is top text.
This is bottom text.
- )
+ );
}
}
```
@@ -97,15 +97,15 @@ React Native does not currently expose an API to access information about device
- If the device has a notch, you may want to increase the status bar height known to the SafeAreaView by doing something like this:
```js
-import { Platform } from 'react-native'
-import { SafeAreaView } from 'react-navigation'
-import DeviceInfo from 'react-native-device-info'
+import { Platform } from 'react-native';
+import { SafeAreaView } from 'react-navigation';
+import DeviceInfo from 'react-native-device-info';
if (Platform.OS === 'android' && DeviceInfo.hasNotch()) {
SafeAreaView
.setStatusBarHeight
/* Some value for status bar height + notch height */
- ()
+ ();
}
```
diff --git a/versioned_docs/version-3.x/headers.md b/versioned_docs/version-3.x/headers.md
index df081469ade..cc00a8848a0 100644
--- a/versioned_docs/version-3.x/headers.md
+++ b/versioned_docs/version-3.x/headers.md
@@ -63,11 +63,11 @@ We only needed the `navigation` prop in the above example but you may in some ca
It's often necessary to update the `navigationOptions` configuration for the active screen from the mounted screen component itself. We can do this using `this.props.navigation.setParams`
```js
- /* Inside of render() */
- this.props.navigation.setParams({otherParam: 'Updated!'})}
- />
+/* Inside of render() */
+ this.props.navigation.setParams({ otherParam: 'Updated!' })}
+/>
```
→ Run this code
@@ -154,7 +154,8 @@ const Home = createStackNavigator(
{
Feed: ExampleScreen,
Profile: ExampleScreen,
- }, {
+ },
+ {
defaultNavigationOptions: {
headerTintColor: '#fff',
headerStyle: {
@@ -168,7 +169,6 @@ const Home = createStackNavigator(
);
const Tabs = createBottomTabNavigator({ Home });
-
```
→ Run this code
@@ -230,11 +230,11 @@ class HomeScreen extends React.Component {
## Additional configuration
-You can read the full list of available `navigationOptions` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+You can read the full list of available `navigationOptions` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator).
## Summary
-- You can customize the header inside of the `navigationOptions` static property on your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+- You can customize the header inside of the `navigationOptions` static property on your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator).
- The `navigationOptions` static property can be an object or a function. When it is a function, it is provided with an object with the `navigation` prop, `screenProps`, and `navigationOptions` on it.
- You can also specify shared `navigationOptions` in the stack navigator configuration when you initialize it. The static property takes precedence over that configuration.
- [Full source of what we have built so far](https://snack.expo.io/@react-navigation/custom-header-title-component-v3).
diff --git a/versioned_docs/version-3.x/hello-react-navigation.md b/versioned_docs/version-3.x/hello-react-navigation.md
index 44088292d8b..bbec78c84a8 100644
--- a/versioned_docs/version-3.x/hello-react-navigation.md
+++ b/versioned_docs/version-3.x/hello-react-navigation.md
@@ -17,14 +17,14 @@ Lets start by demonstrating the most common navigator, `createStackNavigator`.
```javascript
// In App.js in a new project
-import React from "react";
-import { View, Text } from "react-native";
-import { createStackNavigator, createAppContainer } from "react-navigation";
+import React from 'react';
+import { View, Text } from 'react-native';
+import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
-
+
Home Screen
);
@@ -33,8 +33,8 @@ class HomeScreen extends React.Component {
const AppNavigator = createStackNavigator({
Home: {
- screen: HomeScreen
- }
+ screen: HomeScreen,
+ },
});
export default createAppContainer(AppNavigator);
@@ -66,7 +66,7 @@ Given that the only route configuration we have for `Home` is the screen compone
```js
const AppNavigator = createStackNavigator({
- Home: HomeScreen
+ Home: HomeScreen,
});
```
@@ -80,7 +80,7 @@ The ` ` component doesn't accept any props -- all configuration i
class DetailsScreen extends React.Component {
render() {
return (
-
+
Details Screen
);
@@ -90,10 +90,10 @@ class DetailsScreen extends React.Component {
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
- Details: DetailsScreen
+ Details: DetailsScreen,
},
{
- initialRouteName: "Home"
+ initialRouteName: 'Home',
}
);
diff --git a/versioned_docs/version-3.x/localization.md b/versioned_docs/version-3.x/localization.md
index b395f7f93cc..34a7e6b53d6 100644
--- a/versioned_docs/version-3.x/localization.md
+++ b/versioned_docs/version-3.x/localization.md
@@ -11,7 +11,7 @@ English is only one of many languages people speak around the world (thanks a lo
We'll need to use some kind of library to store our translations and provide a function that gives us access to them, along with handling fallbacks when we don't have a particular language defined. Localization and internationalization (i18n) are often used interchangeably, as in the example below where we get the current `locale` from `expo-localization` and use the `i18n-js` library for managing translations, for no particular reason other than it was available - use whatever you like.
```jsx
-import * as Localization from 'expo-localization'; // or whatever library you want
+import * as Localization from 'expo-localization'; // or whatever library you want
import i18n from 'i18n-js'; // or whatever library you want
const en = {
@@ -41,7 +41,7 @@ export default class App extends React.Component {
locale: Localization.locale,
};
- setLocale = locale => {
+ setLocale = (locale) => {
this.setState({ locale });
};
diff --git a/versioned_docs/version-3.x/material-bottom-tab-navigator.md b/versioned_docs/version-3.x/material-bottom-tab-navigator.md
index 1e54e4a71a8..bd63886716d 100644
--- a/versioned_docs/version-3.x/material-bottom-tab-navigator.md
+++ b/versioned_docs/version-3.x/material-bottom-tab-navigator.md
@@ -19,7 +19,7 @@ This API also requires that you install `react-native-vector-icons`! If you are
To use this tab navigator, import it from `react-navigation-material-bottom-tabs`
```js
-import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
+import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';
createMaterialBottomTabNavigator(
RouteConfigs,
@@ -35,30 +35,33 @@ The route configs object is a mapping from route name to a route config.
## MaterialBottomTabNavigatorConfig
-* `shifting` - Whether the shifting style is used, the active tab appears wider and the inactive tabs won't have a label. By default, this is `true` when you have more than 3 tabs.
-* `labeled` - Whether to show labels in tabs. When `false`, only icons will be displayed.
-* `activeColor` - Custom color for icon and label in the active tab.
-* `inactiveColor` - Custom color for icon and label in the inactive tab.
-* `barStyle` - Style for the bottom navigation bar. You can set a bottom padding here if you have a translucent navigation bar on Android: `barStyle={{ paddingBottom: 48 }}`.
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - `initialRoute` to return to initial tab, `order` to return to previous tab, `history` to return to last visited tab, or `none`.
+- `shifting` - Whether the shifting style is used, the active tab appears wider and the inactive tabs won't have a label. By default, this is `true` when you have more than 3 tabs.
+- `labeled` - Whether to show labels in tabs. When `false`, only icons will be displayed.
+- `activeColor` - Custom color for icon and label in the active tab.
+- `inactiveColor` - Custom color for icon and label in the inactive tab.
+- `barStyle` - Style for the bottom navigation bar. You can set a bottom padding here if you have a translucent navigation bar on Android: `barStyle={{ paddingBottom: 48 }}`.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - `initialRoute` to return to initial tab, `order` to return to previous tab, `history` to return to last visited tab, or `none`.
Example:
```js
-export default createMaterialBottomTabNavigator({
- Album: { screen: Album },
- Library: { screen: Library },
- History: { screen: History },
- Cart: { screen: Cart },
-}, {
- initialRouteName: 'Album',
- activeColor: '#f0edf6',
- inactiveColor: '#3e2465',
- barStyle: { backgroundColor: '#694fad' },
-});
+export default createMaterialBottomTabNavigator(
+ {
+ Album: { screen: Album },
+ Library: { screen: Library },
+ History: { screen: History },
+ Cart: { screen: Cart },
+ },
+ {
+ initialRouteName: 'Album',
+ activeColor: '#f0edf6',
+ inactiveColor: '#3e2465',
+ barStyle: { backgroundColor: '#694fad' },
+ }
+);
```
## `navigationOptions` for screens inside of the navigator
@@ -91,8 +94,8 @@ ID to locate this tab button in tests.
Callback to handle press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
Useful for adding a custom logic before the transition to the next scene (the tapped one) starts.
diff --git a/versioned_docs/version-3.x/material-top-tab-navigator.md b/versioned_docs/version-3.x/material-top-tab-navigator.md
index 88fb9b8be02..1ff1aba3fac 100644
--- a/versioned_docs/version-3.x/material-top-tab-navigator.md
+++ b/versioned_docs/version-3.x/material-top-tab-navigator.md
@@ -16,35 +16,35 @@ The route configs object is a mapping from route name to a route config.
## TabNavigatorConfig
-* `initialRouteName` - The routeName for the initial tab route when first loading.
-* `navigationOptions` - Navigation options for the navigator itself, to configure a parent navigator
-* `defaultNavigationOptions` - Default navigation options to use for screens
-* `order` - Array of routeNames which defines the order of the tabs.
-* `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
-* `backBehavior` - `initialRoute` to return to initial tab, `order` to return to previous tab, `history` to return to last visited tab, or `none`.
-* `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`, default is `top`.
-* `swipeEnabled` - Whether to allow swiping between tabs.
-* `animationEnabled` - Whether to animate when changing tabs.
-* `lazy` - Defaults to `false`. If `true`, tabs are rendered only when they are made active or on peek swipe. When `false`, all tabs are rendered immediately.
-* `optimizationsEnabled` - Whether to wrap scenes into [` `](https://github.com/react-navigation/react-navigation-tabs/blob/master/src/views/ResourceSavingScene.js) to move the scene out of the screen once it's unfocused, it improves memory usage.
-* `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view#avoid-one-frame-delay) rendering.
-* `tabBarComponent` - Optional, override the component to use as the tab bar.
-* `tabBarOptions` - An object with the following properties:
- * `activeTintColor` - Label and icon color of the active tab.
- * `inactiveTintColor` - Label and icon color of the inactive tab.
- * `showIcon` - Whether to show icon for tab, default is false.
- * `showLabel` - Whether to show label for tab, default is true.
- * `upperCaseLabel` - Whether to make label uppercase, default is true.
- * `pressColor` - Color for material ripple (Android >= 5.0 only).
- * `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
- * `scrollEnabled` - Whether to enable scrollable tabs.
- * `tabStyle` - Style object for the tab.
- * `indicatorStyle` - Style object for the tab indicator (line at the bottom of the tab).
- * `labelStyle` - Style object for the tab label.
- * `iconStyle` - Style object for the tab icon.
- * `style` - Style object for the tab bar.
- * `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
- * `renderIndicator` - Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
+- `initialRouteName` - The routeName for the initial tab route when first loading.
+- `navigationOptions` - Navigation options for the navigator itself, to configure a parent navigator
+- `defaultNavigationOptions` - Default navigation options to use for screens
+- `order` - Array of routeNames which defines the order of the tabs.
+- `paths` - Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
+- `backBehavior` - `initialRoute` to return to initial tab, `order` to return to previous tab, `history` to return to last visited tab, or `none`.
+- `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`, default is `top`.
+- `swipeEnabled` - Whether to allow swiping between tabs.
+- `animationEnabled` - Whether to animate when changing tabs.
+- `lazy` - Defaults to `false`. If `true`, tabs are rendered only when they are made active or on peek swipe. When `false`, all tabs are rendered immediately.
+- `optimizationsEnabled` - Whether to wrap scenes into [` `](https://github.com/react-navigation/react-navigation-tabs/blob/master/src/views/ResourceSavingScene.js) to move the scene out of the screen once it's unfocused, it improves memory usage.
+- `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view#avoid-one-frame-delay) rendering.
+- `tabBarComponent` - Optional, override the component to use as the tab bar.
+- `tabBarOptions` - An object with the following properties:
+ - `activeTintColor` - Label and icon color of the active tab.
+ - `inactiveTintColor` - Label and icon color of the inactive tab.
+ - `showIcon` - Whether to show icon for tab, default is false.
+ - `showLabel` - Whether to show label for tab, default is true.
+ - `upperCaseLabel` - Whether to make label uppercase, default is true.
+ - `pressColor` - Color for material ripple (Android >= 5.0 only).
+ - `pressOpacity` - Opacity for pressed tab (iOS and Android < 5.0 only).
+ - `scrollEnabled` - Whether to enable scrollable tabs.
+ - `tabStyle` - Style object for the tab.
+ - `indicatorStyle` - Style object for the tab indicator (line at the bottom of the tab).
+ - `labelStyle` - Style object for the tab label.
+ - `iconStyle` - Style object for the tab icon.
+ - `style` - Style object for the tab bar.
+ - `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings, default is true.
+ - `renderIndicator` - Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
Example:
@@ -92,8 +92,8 @@ ID to locate this tab button in tests.
Callback to handle press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
Useful for adding a custom logic before the transition to the next scene (the
tapped one) starts.
@@ -102,5 +102,5 @@ tapped one) starts.
Callback to handle long press events; the argument is an object containing:
-* `navigation`: navigation prop for the screen
-* `defaultHandler`: the default handler for tab press
+- `navigation`: navigation prop for the screen
+- `defaultHandler`: the default handler for tab press
diff --git a/versioned_docs/version-3.x/navigating-without-navigation-prop.md b/versioned_docs/version-3.x/navigating-without-navigation-prop.md
index 7fb78272879..1e87609e130 100644
--- a/versioned_docs/version-3.x/navigating-without-navigation-prop.md
+++ b/versioned_docs/version-3.x/navigating-without-navigation-prop.md
@@ -14,7 +14,9 @@ You can get access to a navigator through a `ref` and pass it to the `Navigation
import { createStackNavigator, createAppContainer } from 'react-navigation';
import NavigationService from './NavigationService';
-const TopLevelNavigator = createStackNavigator({ /* ... */ })
+const TopLevelNavigator = createStackNavigator({
+ /* ... */
+});
const AppContainer = createAppContainer(TopLevelNavigator);
@@ -24,7 +26,7 @@ export default class App extends React.Component {
render() {
return (
{
+ ref={(navigatorRef) => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
diff --git a/versioned_docs/version-3.x/navigating.md b/versioned_docs/version-3.x/navigating.md
index 2c3efd1f221..b6b2877b4c1 100644
--- a/versioned_docs/version-3.x/navigating.md
+++ b/versioned_docs/version-3.x/navigating.md
@@ -48,8 +48,8 @@ class HomeScreen extends React.Component {
Let's break this down:
-* `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
-* `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
+- `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
+- `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
> If we call `this.props.navigation.navigate` with a route name that we haven't defined on a stack navigator, nothing will happen. Said another way, we can only navigate to routes that have been defined on our stack navigator — we cannot navigate to an arbitrary component.
@@ -128,9 +128,9 @@ Another common requirement is to be able to go back _multiple_ screens -- for ex
## Summary
-* `this.props.navigation.navigate('RouteName')` pushes a new route to the stack navigator if it's not already in the stack, otherwise it jumps to that screen.
-* We can call `this.props.navigation.push('RouteName')` as many times as we like and it will continue pushing routes.
-* The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
-* You can go back to an existing screen in the stack with `this.props.navigation.navigate('RouteName')`, and you can go back to the first screen in the stack with `this.props.navigation.popToTop()`.
-* The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
-* [Full source of what we have built so far](https://snack.expo.io/@react-navigation/going-back-v3).
+- `this.props.navigation.navigate('RouteName')` pushes a new route to the stack navigator if it's not already in the stack, otherwise it jumps to that screen.
+- We can call `this.props.navigation.push('RouteName')` as many times as we like and it will continue pushing routes.
+- The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
+- You can go back to an existing screen in the stack with `this.props.navigation.navigate('RouteName')`, and you can go back to the first screen in the stack with `this.props.navigation.popToTop()`.
+- The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
+- [Full source of what we have built so far](https://snack.expo.io/@react-navigation/going-back-v3).
diff --git a/versioned_docs/version-3.x/navigation-actions.md b/versioned_docs/version-3.x/navigation-actions.md
index 3ac71e92270..a0ff2cc460d 100644
--- a/versioned_docs/version-3.x/navigation-actions.md
+++ b/versioned_docs/version-3.x/navigation-actions.md
@@ -10,10 +10,9 @@ Note that if you want to dispatch react-navigation actions you should use the ac
The following actions are supported:
-* [Navigate](#navigate) - Navigate to another route
-* [Back](#back) - Go back to previous state
-* [Set Params](#setparams) - Set Params for given route
-* [Init](#init) - Used to initialize first state if state is undefined
+- [Navigate](#navigate) - Navigate to another route
+- [Back](#back) - Go back to previous state
+- [Set Params](#setparams) - Set Params for given route
For actions specific to a StackNavigator, see [StackActions](stack-actions.md).
@@ -23,10 +22,10 @@ The action creator functions define `toString()` to return the action type, whic
The `navigate` action will update the current state with the result of a `navigate` action.
-* `routeName` - _String_ - Required - A destination routeName that has been registered somewhere in the app's router
-* `params` - _Object_ - Optional - Params to merge into the destination route
-* `action` - _Object_ - Optional - (advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the actions described in this doc can be set as a sub-action.
-* `key` - _String_ - Optional - The identifier for the route to navigate to. Navigate back to this route if it already exists
+- `routeName` - _String_ - Required - A destination routeName that has been registered somewhere in the app's router
+- `params` - _Object_ - Optional - Params to merge into the destination route
+- `action` - _Object_ - Optional - (advanced) The sub-action to run in the child router, if the screen is a navigator. Any one of the actions described in this doc can be set as a sub-action.
+- `key` - _String_ - Optional - The identifier for the route to navigate to. Navigate back to this route if it already exists
```js
import { NavigationActions } from 'react-navigation';
@@ -46,7 +45,7 @@ this.props.navigation.dispatch(navigateAction);
Go back to previous screen and close current screen. `back` action creator takes in one optional parameter:
-* `key` - _string or null_ - optional - If set, navigation will go back from the given key. If null, navigation will go back anywhere.
+- `key` - _string or null_ - optional - If set, navigation will go back from the given key. If null, navigation will go back anywhere.
```js
import { NavigationActions } from 'react-navigation';
@@ -61,8 +60,8 @@ this.props.navigation.dispatch(backAction);
When dispatching `setParams`, the router will produce a new state that has changed the params of a particular route, as identified by the key
-* `params` - _object_ - required - New params to be merged into existing route params
-* `key` - _string_ - required - Route key that should get the new params
+- `params` - _object_ - required - New params to be merged into existing route params
+- `key` - _string_ - required - Route key that should get the new params
```js
import { NavigationActions } from 'react-navigation';
diff --git a/versioned_docs/version-3.x/navigation-context.md b/versioned_docs/version-3.x/navigation-context.md
index 4232431d886..889e14e85db 100644
--- a/versioned_docs/version-3.x/navigation-context.md
+++ b/versioned_docs/version-3.x/navigation-context.md
@@ -22,22 +22,20 @@ export function useFocusState() {
const newState = focusStateOfEvent(e.type);
newState && setFocusState(newState);
}
- useEffect(
- () => {
- const subsA = navigation.addListener('action', handleEvt);
- const subsWF = navigation.addListener('willFocus', handleEvt);
- const subsDF = navigation.addListener('didFocus', handleEvt);
- const subsWB = navigation.addListener('willBlur', handleEvt);
- const subsDB = navigation.addListener('didBlur', handleEvt);
- return () => {
- subsA.remove();
- subsWF.remove();
- subsDF.remove();
- subsWB.remove();
- subsDB.remove();
- };
- },
- );
+ useEffect(() => {
+ const subsA = navigation.addListener('action', handleEvt);
+ const subsWF = navigation.addListener('willFocus', handleEvt);
+ const subsDF = navigation.addListener('didFocus', handleEvt);
+ const subsWB = navigation.addListener('willBlur', handleEvt);
+ const subsDB = navigation.addListener('didBlur', handleEvt);
+ return () => {
+ subsA.remove();
+ subsWF.remove();
+ subsDF.remove();
+ subsWB.remove();
+ subsDB.remove();
+ };
+ });
return focusState;
}
```
diff --git a/versioned_docs/version-3.x/navigation-events.md b/versioned_docs/version-3.x/navigation-events.md
index 802305cd658..a258d361e33 100644
--- a/versioned_docs/version-3.x/navigation-events.md
+++ b/versioned_docs/version-3.x/navigation-events.md
@@ -8,13 +8,13 @@ sidebar_label: NavigationEvents
### Component props
-* `navigation` - navigation props (optional, defaults to reading from React context)
-* `onWillFocus` - event listener
-* `onDidFocus` - event listener
-* `onWillBlur` - event listener
-* `onDidBlur` - event listener
+- `navigation` - navigation props (optional, defaults to reading from React context)
+- `onWillFocus` - event listener
+- `onDidFocus` - event listener
+- `onWillBlur` - event listener
+- `onDidBlur` - event listener
-The event listener is the same as the imperative [`navigation.addListener(...)`](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle) API.
+The event listener is the same as the imperative [`navigation.addListener(...)`](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle) API.
### Example
@@ -26,10 +26,10 @@ import { NavigationEvents } from 'react-navigation';
const MyScreen = () => (
console.log('will focus',payload)}
- onDidFocus={payload => console.log('did focus',payload)}
- onWillBlur={payload => console.log('will blur',payload)}
- onDidBlur={payload => console.log('did blur',payload)}
+ onWillFocus={(payload) => console.log('will focus', payload)}
+ onDidFocus={(payload) => console.log('did focus', payload)}
+ onWillBlur={(payload) => console.log('will blur', payload)}
+ onDidBlur={(payload) => console.log('did blur', payload)}
/>
{/*
Your view code
diff --git a/versioned_docs/version-3.x/navigation-key.md b/versioned_docs/version-3.x/navigation-key.md
index 6cfff3dc734..941c6189082 100644
--- a/versioned_docs/version-3.x/navigation-key.md
+++ b/versioned_docs/version-3.x/navigation-key.md
@@ -10,21 +10,21 @@ The `key` parameter comes up repeatedly across different navigation functions. L
If no key is provided, `StackRouter` will behave as follows:
-* if a route with the given name already exists in the state, `StackRouter` will jump to the existing route, along with setting the new parameters.
-* if no such route exists, `StackRouter` will push it onto the stack
+- if a route with the given name already exists in the state, `StackRouter` will jump to the existing route, along with setting the new parameters.
+- if no such route exists, `StackRouter` will push it onto the stack
If, however, you want to push several instances of the same route, you can do so by providing a unique `key` parameter each time you call `navigate`, or you can use the `push` action available on `StackRouter`. See the related [RFC](https://github.com/react-navigation/rfcs/blob/master/text/0004-less-pushy-navigate.md) for more background.
> Note: the behavior of `navigate` without a `key` is significantly different in the 1.x series of releases. Read more about it [here](https://gist.github.com/vonovak/ef72f5efe1d36742de8968ff6a708985).
-### Usage with [`reset`](navigation-actions.md#reset)
+### Usage with [`reset`](stack-actions.md#reset)
When resetting, `key` is also optional and can be a string or `null`. If set, the navigator with the given key will reset. If `null`, the root navigator will reset. You can obtain a route's navigator key by calling `this.props.navigation.dangerouslyGetParent().state.key`. Reason why the function is called `dangerouslyGetParent` is to warn developers against overusing it to eg. get parent of parent and other hard-to-follow patterns.
-### Usage with [`replace`](navigation-actions.md#replace)
+### Usage with [`replace`](stack-actions.md#replace)
With the `replace` navigation action, `key` is a required parameter used for identifying the route to be replaced. If you use the helper function `this.props.navigation.replace`, we will automatically substitute the key of the current route.
### Usage with `goBack`
-Please refer to the [`goBack docs`](navigation-prop.md#goback-close-the-active-screen-and-move-back) for a detailed explanation.
+Please refer to the [`goBack docs`](navigation-prop.md#goback---close-the-active-screen-and-move-back) for a detailed explanation.
diff --git a/versioned_docs/version-3.x/navigation-lifecycle.md b/versioned_docs/version-3.x/navigation-lifecycle.md
index bc1c1abcc1d..e6210d5f11e 100644
--- a/versioned_docs/version-3.x/navigation-lifecycle.md
+++ b/versioned_docs/version-3.x/navigation-lifecycle.md
@@ -29,12 +29,10 @@ const SettingsStack = createStackNavigator({
Profile: ProfileScreen,
});
-const TabNavigator = createBottomTabNavigator(
- {
- Home: HomeStack,
- Settings: SettingsStack,
- }
-);
+const TabNavigator = createBottomTabNavigator({
+ Home: HomeStack,
+ Settings: SettingsStack,
+});
```
We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the tab bar to switch to the `SettingsScreen` and navigate to `ProfileScreen`. After this sequence of operations is done, all 4 of the screens are mounted! If you use the tab bar to switch back to the `HomeStack`, you'll notice you'll be presented with the `DetailsScreen` - the navigation state of the `HomeStack` has been preserved!
@@ -43,7 +41,7 @@ We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the ta
Now that we understand how React lifecycle methods work in React Navigation, let's answer the question we asked at the beginning: "How do we find out that a user is leaving it or coming back to it?"
-React Navigation emits events to screen components that subscribe to them. There are four different events that you can subscribe to: `willFocus`, `willBlur`, `didFocus` and `didBlur`. Read more about them in the [API reference](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle).
+React Navigation emits events to screen components that subscribe to them. There are four different events that you can subscribe to: `willFocus`, `willBlur`, `didFocus` and `didBlur`. Read more about them in the [API reference](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle).
Many of your use cases may be covered with the [`withNavigationFocus` HOC](with-navigation-focus.md) or the [` ` component](navigation-events.md) which are a little more straightforward to use.
diff --git a/versioned_docs/version-3.x/navigation-options-resolution.md b/versioned_docs/version-3.x/navigation-options-resolution.md
index 04292050a71..3ab0a7263e9 100644
--- a/versioned_docs/version-3.x/navigation-options-resolution.md
+++ b/versioned_docs/version-3.x/navigation-options-resolution.md
@@ -32,10 +32,12 @@ class B extends React.Component {
const HomeStack = createStackNavigator({ A });
const SettingsStack = createStackNavigator({ B });
-export default createAppContainer(createBottomTabNavigator({
- HomeStack,
- SettingsStack,
-}));
+export default createAppContainer(
+ createBottomTabNavigator({
+ HomeStack,
+ SettingsStack,
+ })
+);
```
→ Run this code
@@ -54,10 +56,12 @@ SettingsStack.navigationOptions = {
tabBarLabel: 'Settings!',
};
-export default createAppContainer(createBottomTabNavigator({
- HomeStack,
- SettingsStack,
-}));
+export default createAppContainer(
+ createBottomTabNavigator({
+ HomeStack,
+ SettingsStack,
+ })
+);
```
→ Run this code
@@ -84,13 +88,16 @@ MyOtherComponent.navigationOptions = {
We also know that `createStackNavigator` and related functions return React components. So when we set the `navigationOptions` directly on the `HomeStack` and `SettingsStack` component, it allows us to control the `navigationOptions` for its parent navigator when its used as a screen component. In this case, the `navigationOptions` on our stack components configure the label in the tab navigator that renders the stacks.
```js
-const HomeStack = createStackNavigator({ A }, {
- // This is the default for screens in the stack, so `A` will
- // use this title unless it overrides it
- defaultNavigationOptions: {
- title: 'Welcome'
+const HomeStack = createStackNavigator(
+ { A },
+ {
+ // This is the default for screens in the stack, so `A` will
+ // use this title unless it overrides it
+ defaultNavigationOptions: {
+ title: 'Welcome',
+ },
}
-})
+);
// These are the options that are used by the navigator that renders
// the HomeStack, in our example above this is a tab navigator.
@@ -102,21 +109,24 @@ HomeStack.navigationOptions = {
Another way you could write this is:
```js
-const HomeStack = createStackNavigator({ A }, {
- // This applies to the parent navigator
- navigationOptions: {
- tabBarLabel: 'Home!',
- },
- // This applies to child routes
- defaultNavigationOptions: {
- title: 'Welcome'
+const HomeStack = createStackNavigator(
+ { A },
+ {
+ // This applies to the parent navigator
+ navigationOptions: {
+ tabBarLabel: 'Home!',
+ },
+ // This applies to child routes
+ defaultNavigationOptions: {
+ title: 'Welcome',
+ },
}
-});
+);
```
→ Run this code
-# getActiveChildNavigationOptions
+## getActiveChildNavigationOptions
If you would like to get the `navigationOptions` from the active child of a navigator, you can do that with `getActiveChildNavigationOptions`. This makes it possible for you to set the `tabBarLabel` directly on a screen inside of a stack that is inside of a tab, for example.
@@ -132,23 +142,26 @@ class A extends React.Component {
}
}
-const HomeStack = createStackNavigator({ A }, {
- navigationOptions: ({ navigation, screenProps }) => ({
- // you can put fallback values before here, eg: a default tabBarLabel
- ...getActiveChildNavigationOptions(navigation, screenProps),
- // put other navigationOptions that you don't want the active child to
- // be able to override here!
- })
-});
+const HomeStack = createStackNavigator(
+ { A },
+ {
+ navigationOptions: ({ navigation, screenProps }) => ({
+ // you can put fallback values before here, eg: a default tabBarLabel
+ ...getActiveChildNavigationOptions(navigation, screenProps),
+ // put other navigationOptions that you don't want the active child to
+ // be able to override here!
+ }),
+ }
+);
```
→ Run this code
-# **Note**: the navigationOptions property vs navigator configuration
+## **Note**: the navigationOptions property vs navigator configuration
Navigators are initialized with `create*Navigator(routeConfig, navigatorConfig)`. Inside of `navigatorConfig` we can add a `defaultNavigationOptions` property. These `defaultNavigationOptions` are the default options for screens within that navigator ([read more about sharing common navigationOptions](headers.md#sharing-common-navigationoptions-across-screens)), they do not refer to the `navigationOptions` for that navigator — as we have seen above, we set the `navigationOptions` property directly on the navigator for that use case.
-# A stack contains a tab navigator and you want to set the title on the stack header
+## A stack contains a tab navigator and you want to set the title on the stack header
Imagine the following configuration:
@@ -217,7 +230,7 @@ Using this configuration, the `headerTitle` or `title` from `navigationOptions`
Additionally, you can push new screens to the feed and profile stacks without hiding the tab bar by adding more routes to those stacks. If you want to push screens on top of the tab bar, then you can add them to the `AppNavigator` stack.
-# A tab navigator contains a stack and you want to hide the tab bar on specific screens
+## A tab navigator contains a stack and you want to hide the tab bar on specific screens
Similar to the example above where a stack contains a tab navigator, we can solve this in two ways: add `navigationOptions` to our tab navigator to set the tab bar to hidden depending on which route is active in the child stack, or we can move the tab navigator inside of the stack.
@@ -287,7 +300,7 @@ const AppNavigator = createSwitchNavigator({
});
```
-# A drawer has a stack inside of it and you want to lock the drawer on certain screens
+## A drawer has a stack inside of it and you want to lock the drawer on certain screens
This is conceptually identical to having a tab with a stack inside of it (read that above if you have not already), where you want to hide the tab bar on certain screens. The only difference is that rather than using `tabBarVisible` you will use `drawerLockMode`.
diff --git a/versioned_docs/version-3.x/navigation-prop.md b/versioned_docs/version-3.x/navigation-prop.md
index c45040d67e2..a34fe0d9e0d 100644
--- a/versioned_docs/version-3.x/navigation-prop.md
+++ b/versioned_docs/version-3.x/navigation-prop.md
@@ -6,16 +6,16 @@ sidebar_label: Navigation prop
Each `screen` component in your app is provided with the `navigation` prop automatically. The prop contains various convenience functions that dispatch navigation actions on the route's router. It looks like this:
-* `this.props.navigation`
- * `navigate` - go to another screen, figures out the action it needs to take to do it
- * `goBack` - close active screen and move back in the stack
- * `addListener` - subscribe to updates to navigation lifecycle
- * `isFocused` - function that returns `true` if the screen is focused and `false` otherwise.
- * `state` - current state/routes
- * `setParams` - make changes to route's params
- * `getParam` - get a specific param with fallback
- * `dispatch` - send an action to router
- * `dangerouslyGetParent` - function that returns the parent navigator, if any
+- `this.props.navigation`
+ - `navigate` - go to another screen, figures out the action it needs to take to do it
+ - `goBack` - close active screen and move back in the stack
+ - `addListener` - subscribe to updates to navigation lifecycle
+ - `isFocused` - function that returns `true` if the screen is focused and `false` otherwise.
+ - `state` - current state/routes
+ - `setParams` - make changes to route's params
+ - `getParam` - get a specific param with fallback
+ - `dispatch` - send an action to router
+ - `dangerouslyGetParent` - function that returns the parent navigator, if any
It's important to highlight the `navigation` prop is _not_ passed in to _all_ components; only `screen` components receive this prop automatically! React Navigation doesn't do anything magic here. For example, if you were to define a `MyBackButton` component and render it as a child of a screen component, you would not be able to access the `navigation` prop on it. If, however, you wish to access the `navigation` prop in any of your components, you may use the [`withNavigation`](with-navigation.md) HOC.
@@ -25,20 +25,20 @@ There are several additional functions present on `this.props.navigation` based
If the navigator is a stack navigator, several alternatives to `navigate` and `goBack` are provided and you can use whichever you prefer. The functions are:
-* `this.props.navigation`
- * `push` - push a new route onto the stack
- * `pop` - go back in the stack
- * `popToTop` - go to the top of the stack
- * `replace` - replace the current route with a new one
- * `reset` - wipe the navigator state and replace it with the result of several actions
- * `dismiss` - dismiss the current stack
+- `this.props.navigation`
+ - `push` - push a new route onto the stack
+ - `pop` - go back in the stack
+ - `popToTop` - go to the top of the stack
+ - `replace` - replace the current route with a new one
+ - `reset` - wipe the navigator state and replace it with the result of several actions
+ - `dismiss` - dismiss the current stack
If the navigator is a drawer navigator, the following are also available:
-* `this.props.navigation`
- * `openDrawer` - open the drawer
- * `closeDrawer` - close the drawer
- * `toggleDrawer` - toggle the state, ie. switch from closed to open and vice versa
+- `this.props.navigation`
+ - `openDrawer` - open the drawer
+ - `closeDrawer` - close the drawer
+ - `toggleDrawer` - toggle the state, ie. switch from closed to open and vice versa
## Common API reference
@@ -54,10 +54,10 @@ OR
`navigation.navigate(routeName, params, action)`
-* `routeName` - A destination routeName that has been registered somewhere in the app's router
-* `params` - Params to merge into the destination route
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
-* `key` - Optional identifier of what route to navigate to. Navigate **back** to this route, if it already exists
+- `routeName` - A destination routeName that has been registered somewhere in the app's router
+- `params` - Params to merge into the destination route
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
+- `key` - Optional identifier of what route to navigate to. Navigate **back** to this route, if it already exists
```js
class HomeScreen extends React.Component {
@@ -106,10 +106,10 @@ class HomeScreen extends React.Component {
Consider the following navigation stack history:
```javascript
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_A});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_B});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_C});
-navigation.navigate({routeName: SCREEN, key: SCREEN_KEY_D});
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_A });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_B });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_C });
+navigation.navigate({ routeName: SCREEN, key: SCREEN_KEY_D });
```
Now you are on _screen D_ and want to go back to _screen A_ (popping D, C, and B).
@@ -125,17 +125,17 @@ Alternatively, as _screen A_ is the top of the stack, you can use `navigation.po
React Navigation emits events to screen components that subscribe to them:
-* `willFocus` - the screen will focus
-* `didFocus` - the screen focused (if there was a transition, the transition completed)
-* `willBlur` - the screen will be unfocused
-* `didBlur` - the screen unfocused (if there was a transition, the transition completed)
+- `willFocus` - the screen will focus
+- `didFocus` - the screen focused (if there was a transition, the transition completed)
+- `willBlur` - the screen will be unfocused
+- `didBlur` - the screen unfocused (if there was a transition, the transition completed)
Example:
```javascript
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
- payload => {
+ (payload) => {
console.debug('didBlur', payload);
}
);
@@ -239,19 +239,19 @@ The following actions will work within any stack navigator:
Similar to navigate, push will move you forward to a new route in the stack. This differs from `navigate` in that `navigate` will pop back to earlier in the stack if a route of the given name is already present there. `push` will always add on top, so a route can be present multiple times.
```js
-navigation.push(routeName, params, action)
+navigation.push(routeName, params, action);
```
-* `routeName` - A destination routeName that has been registered somewhere in the app's router.
-* `params` - Params to merge into the destination route.
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
+- `routeName` - A destination routeName that has been registered somewhere in the app's router.
+- `params` - Params to merge into the destination route.
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator. See [Actions Doc](navigation-actions.md) for a full list of supported actions.
### Pop
Take you to the previous screen in the stack. If you provide a number, `n`, it will specify how many screens to take you back within the stack.
```js
-navigation.pop(n)
+navigation.pop(n);
```
### PopToTop
@@ -259,7 +259,7 @@ navigation.pop(n)
Call this to jump back to the top route in the stack, dismissing all other screens.
```js
-navigation.popToTop()
+navigation.popToTop();
```
### Replace
@@ -267,7 +267,7 @@ navigation.popToTop()
Call this to replace the current screen with the given route, with params and sub-action.
```js
-navigation.replace(routeName, params, action)
+navigation.replace(routeName, params, action);
```
### Reset
@@ -275,7 +275,7 @@ navigation.replace(routeName, params, action)
Wipe the navigator state and replace it with the result of several actions.
```js
-navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0)
+navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0);
```
### Dismiss
@@ -283,7 +283,7 @@ navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0)
Call this if you're in a nested (child) stack and want to dismiss the entire stack, returning to the parent stack.
```js
-navigation.dismiss()
+navigation.dismiss();
```
## Advanced API Reference
@@ -330,9 +330,8 @@ class UserCreateScreen extends Component {
return {
title: 'New User',
- gesturesEnabled
+ gesturesEnabled,
};
};
}
-
```
diff --git a/versioned_docs/version-3.x/params.md b/versioned_docs/version-3.x/params.md
index 2806be01dac..d0c6a250f4b 100644
--- a/versioned_docs/version-3.x/params.md
+++ b/versioned_docs/version-3.x/params.md
@@ -54,7 +54,8 @@ class DetailsScreen extends React.Component {
onPress={() =>
this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
- })}
+ })
+ }
/>
Count: {this.props.value}
+ return Count: {this.props.value} ;
}
}
-let CountContainer = connect(state => ({ value: state.count }))(Count);
+let CountContainer = connect((state) => ({ value: state.count }))(Count);
class Counter extends React.Component {
static navigationOptions = {
- title:
+ title: ,
};
/* .. the rest of the code */
diff --git a/versioned_docs/version-3.x/routers.md b/versioned_docs/version-3.x/routers.md
index 691c1de8957..7d24d0e99ce 100644
--- a/versioned_docs/version-3.x/routers.md
+++ b/versioned_docs/version-3.x/routers.md
@@ -35,12 +35,15 @@ See the [Custom Router API spec](custom-routers.md) to learn about the API of `S
To override navigation behavior, you can override the navigation state logic in `getStateForAction`, and manually manipulate the `routes` and `index`.
```js
-const MyApp = createStackNavigator({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
+const MyApp = createStackNavigator(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
const defaultGetStateForAction = MyApp.router.getStateForAction;
@@ -48,8 +51,8 @@ MyApp.router.getStateForAction = (action, state) => {
if (state && action.type === 'PushTwoProfiles') {
const routes = [
...state.routes,
- {key: 'A', routeName: 'Profile', params: { name: action.name1 }},
- {key: 'B', routeName: 'Profile', params: { name: action.name2 }},
+ { key: 'A', routeName: 'Profile', params: { name: action.name1 } },
+ { key: 'B', routeName: 'Profile', params: { name: action.name2 } },
];
return {
...state,
@@ -66,14 +69,17 @@ MyApp.router.getStateForAction = (action, state) => {
Sometimes you may want to prevent some navigation activity, depending on your route.
```js
-import { NavigationActions } from 'react-navigation'
+import { NavigationActions } from 'react-navigation';
-const MyStackRouter = StackRouter({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
+const MyStackRouter = StackRouter(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
const defaultGetStateForAction = MyStackRouter.router.getStateForAction;
@@ -97,22 +103,23 @@ MyStackRouter.router.getStateForAction = (action, state) => {
Perhaps your app has a unique URI which the built-in routers cannot handle. You can always extend the router `getActionForPathAndParams`.
```js
-import { NavigationActions } from 'react-navigation'
+import { NavigationActions } from 'react-navigation';
-const MyApp = createStackNavigator({
- Home: { screen: HomeScreen },
- Profile: { screen: ProfileScreen },
-}, {
- initialRouteName: 'Home',
-})
-const previousGetActionForPathAndParams = MyApp.router.getActionForPathAndParams;
+const MyApp = createStackNavigator(
+ {
+ Home: { screen: HomeScreen },
+ Profile: { screen: ProfileScreen },
+ },
+ {
+ initialRouteName: 'Home',
+ }
+);
+const previousGetActionForPathAndParams =
+ MyApp.router.getActionForPathAndParams;
Object.assign(MyApp.router, {
getActionForPathAndParams(path, params) {
- if (
- path === 'my/custom/path' &&
- params.magic === 'yes'
- ) {
+ if (path === 'my/custom/path' && params.magic === 'yes') {
// returns a profile navigate action for /my/custom/path?magic=yes
return NavigationActions.navigate({
routeName: 'Profile',
diff --git a/versioned_docs/version-3.x/scrollables.md b/versioned_docs/version-3.x/scrollables.md
index ab5de11096d..5c9e252acf7 100644
--- a/versioned_docs/version-3.x/scrollables.md
+++ b/versioned_docs/version-3.x/scrollables.md
@@ -11,7 +11,11 @@ Example
```jsx harmony
import React from 'react';
import { Text, View } from 'react-native';
-import { createBottomTabNavigator, createAppContainer, FlatList } from 'react-navigation';
+import {
+ createBottomTabNavigator,
+ createAppContainer,
+ FlatList,
+} from 'react-navigation';
const data = new Array(150).fill(0);
diff --git a/versioned_docs/version-3.x/stack-actions.md b/versioned_docs/version-3.x/stack-actions.md
index cdf48afae9b..bad6b5d5db1 100644
--- a/versioned_docs/version-3.x/stack-actions.md
+++ b/versioned_docs/version-3.x/stack-actions.md
@@ -8,19 +8,19 @@ sidebar_label: StackActions
The following actions are supported:
-* [Reset](#reset) - Replace current state with a new state
-* [Replace](#replace) - Replace a route at a given key with another route
-* [Push](#push) - Add a route on the top of the stack, and navigate forward to it
-* [Pop](#pop) - Navigate back to previous routes
-* [PopToTop](#poptotop) - Navigate to the top route of the stack, dismissing all other routes
+- [Reset](#reset) - Replace current state with a new state
+- [Replace](#replace) - Replace a route at a given key with another route
+- [Push](#push) - Add a route on the top of the stack, and navigate forward to it
+- [Pop](#pop) - Navigate back to previous routes
+- [PopToTop](#poptotop) - Navigate to the top route of the stack, dismissing all other routes
### reset
The `reset` action wipes the whole navigation state and replaces it with the result of several actions.
-* `index` - _number_ - required - Index of the active route on `routes` array in navigation `state`.
-* `actions` - _array_ - required - Array of Navigation Actions that will replace the navigation state.
-* `key` - _string or null_ - optional - If set, the navigator with the given key will reset. If null, the root navigator will reset.
+- `index` - _number_ - required - Index of the active route on `routes` array in navigation `state`.
+- `actions` - _array_ - required - Array of Navigation Actions that will replace the navigation state.
+- `key` - _string or null_ - optional - If set, the navigator with the given key will reset. If null, the root navigator will reset.
```js
import { StackActions, NavigationActions } from 'react-navigation';
@@ -56,20 +56,20 @@ this.props.navigation.dispatch(resetAction);
The `replace` action replaces the route at the given key with another route.
-* `key` - _string_ - Key of the route to replace. If this is not defined, the most recent route will be replaced.
-* `newKey` - _string_ - Key to use for the replacement route. Generated automatically if not provided.
-* `routeName` - _string_ - `routeName` to use for replacement route.
-* `params` - _object_ - Parameters to pass in to the replacement route.
-* `action` - _object_ - Optional sub-action.
-* `immediate`*- _boolean_ -*Currently has no effect, this is a placeholder for when stack navigator supports animated replace (it currently does not).
+- `key` - _string_ - Key of the route to replace. If this is not defined, the most recent route will be replaced.
+- `newKey` - _string_ - Key to use for the replacement route. Generated automatically if not provided.
+- `routeName` - _string_ - `routeName` to use for replacement route.
+- `params` - _object_ - Parameters to pass in to the replacement route.
+- `action` - _object_ - Optional sub-action.
+- `immediate`*- *boolean* -*Currently has no effect, this is a placeholder for when stack navigator supports animated replace (it currently does not).
### push
The `push` action adds a route on top of the stack and navigates forward to it. This differs from `navigate` in that `navigate` will pop back to earlier in the stack if a route of the given name is already present there. `push` will always add on top, so a route can be present multiple times.
-* `routeName` - _string_ - `routeName` to push onto the stack.
-* `params` - _object_ - Screen params to merge into the destination route (found in the pushed screen through `this.props.navigation.state.params`).
-* `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator.
+- `routeName` - _string_ - `routeName` to push onto the stack.
+- `params` - _object_ - Screen params to merge into the destination route (found in the pushed screen through `this.props.navigation.state.params`).
+- `action` - (advanced) The sub-action to run in the child router, if the screen is a navigator.
```js
import { StackActions } from 'react-navigation';
@@ -88,7 +88,7 @@ this.props.navigation.dispatch(pushAction);
The `pop` action takes you back to a previous screen in the stack. The `n` param allows you to specify how many screens to pop back by.
-* `n` - _number_ - The number of screens to pop back by.
+- `n` - _number_ - The number of screens to pop back by.
```js
import { StackActions } from 'react-navigation';
diff --git a/versioned_docs/version-3.x/stack-navigator.md b/versioned_docs/version-3.x/stack-navigator.md
index d7b5b9f38a0..7afdfa40049 100644
--- a/versioned_docs/version-3.x/stack-navigator.md
+++ b/versioned_docs/version-3.x/stack-navigator.md
@@ -44,41 +44,41 @@ createStackNavigator({
Options for the router:
-* `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
-* `initialRouteParams` - The params for the initial route
-* `initialRouteKey` - Optional identifier of the initial route
-* `navigationOptions` - Navigation options for the navigator itself, to configure a parent navigator
-* `defaultNavigationOptions` - Default navigation options to use for screens
+- `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
+- `initialRouteParams` - The params for the initial route
+- `initialRouteKey` - Optional identifier of the initial route
+- `navigationOptions` - Navigation options for the navigator itself, to configure a parent navigator
+- `defaultNavigationOptions` - Default navigation options to use for screens
-* `paths` - A mapping of overrides for the paths set in the route configs
-* `disableKeyboardHandling` - If true, the keyboard will NOT automatically dismiss when navigating to a new screen. Defaults to false. This is ignored in the web platform.
+- `paths` - A mapping of overrides for the paths set in the route configs
+- `disableKeyboardHandling` - If true, the keyboard will NOT automatically dismiss when navigating to a new screen. Defaults to false. This is ignored in the web platform.
Visual options:
-* `mode` - Defines the style for rendering and transitions:
- * `card` - Use the standard iOS and Android screen transitions. This is the default.
- * `modal` - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
-* `headerMode` - Specifies how the header should be rendered:
- * `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
- * `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
- * `none` - No header will be rendered.
-* `headerBackTitleVisible` - A reasonable default is supplied for whether the back button title should be visible or not, but if you want to override that you can use `true` or `false` in this option.
-* `headerTransitionPreset` - Specifies how the header should transition from one screen to another when `headerMode: float` is enabled.
- * `fade-in-place` - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
- * `uikit` - An approximation of the default behavior for iOS.
-* `headerLayoutPreset` - Specifies how to lay out the header components.
- * `left` - Anchor the title to the left, near the back button or other left component. This is the default on Android. When used on iOS, the header back title is hidden. Content from the left component will overflow underneath the title, if you need to adjust this you can use `headerLeftContainerStyle` and `headerTitleContainerStyle`. Additionally, this alignment is incompatible with `headerTransitionPreset: 'uikit'`.
- * `center` - Center the title, this is the default on iOS.
-* `cardStyle` - Use this prop to override or extend the default style for an individual card in stack.
-* `cardShadowEnabled` - Use this prop to have visible shadows during transitions. Defaults to `true`
-* `cardOverlayEnabled` - Use this prop to have visible stack card overlays during transitions. Defaults to `false`.
-* `transitionConfig` - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](https://github.com/react-navigation/react-navigation/blob/3.x/flow/react-navigation.js)). Provided function will be passed the following arguments:
- * `transitionProps` - Transition props for the new screen.
- * `prevTransitionProps` - Transitions props for the old screen.
- * `isModal` - Boolean specifying if screen is modal.
-* `onTransitionStart` - Function to be invoked when the card transition animation is about to start.
-* `onTransitionEnd` - Function to be invoked once the card transition animation completes.
-* `transparentCard` - *Experimental* - Prop to keep all cards in the stack visible and add a transparent background instead of a white one. This is useful to implement things like modal dialogs where the previous scene should still be visible underneath the current one.
+- `mode` - Defines the style for rendering and transitions:
+ - `card` - Use the standard iOS and Android screen transitions. This is the default.
+ - `modal` - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
+- `headerMode` - Specifies how the header should be rendered:
+ - `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
+ - `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
+ - `none` - No header will be rendered.
+- `headerBackTitleVisible` - A reasonable default is supplied for whether the back button title should be visible or not, but if you want to override that you can use `true` or `false` in this option.
+- `headerTransitionPreset` - Specifies how the header should transition from one screen to another when `headerMode: float` is enabled.
+ - `fade-in-place` - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
+ - `uikit` - An approximation of the default behavior for iOS.
+- `headerLayoutPreset` - Specifies how to lay out the header components.
+ - `left` - Anchor the title to the left, near the back button or other left component. This is the default on Android. When used on iOS, the header back title is hidden. Content from the left component will overflow underneath the title, if you need to adjust this you can use `headerLeftContainerStyle` and `headerTitleContainerStyle`. Additionally, this alignment is incompatible with `headerTransitionPreset: 'uikit'`.
+ - `center` - Center the title, this is the default on iOS.
+- `cardStyle` - Use this prop to override or extend the default style for an individual card in stack.
+- `cardShadowEnabled` - Use this prop to have visible shadows during transitions. Defaults to `true`
+- `cardOverlayEnabled` - Use this prop to have visible stack card overlays during transitions. Defaults to `false`.
+- `transitionConfig` - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](https://github.com/react-navigation/react-navigation/blob/3.x/flow/react-navigation.js)). Provided function will be passed the following arguments:
+ - `transitionProps` - Transition props for the new screen.
+ - `prevTransitionProps` - Transitions props for the old screen.
+ - `isModal` - Boolean specifying if screen is modal.
+- `onTransitionStart` - Function to be invoked when the card transition animation is about to start.
+- `onTransitionEnd` - Function to be invoked once the card transition animation completes.
+- `transparentCard` - _Experimental_ - Prop to keep all cards in the stack visible and add a transparent background instead of a white one. This is useful to implement things like modal dialogs where the previous scene should still be visible underneath the current one.
### `navigationOptions` for screens inside of the navigator
@@ -116,7 +116,7 @@ StackNavigator({
screen: AScreen,
navigationOptions: () => ({
title: `A`,
- headerBackTitle: null
+ headerBackTitle: null,
}),
},
B: {
@@ -124,7 +124,7 @@ StackNavigator({
navigationOptions: () => ({
title: `B`,
}),
- }
+ },
});
```
@@ -139,7 +139,7 @@ StackNavigator({
navigationOptions: () => ({
title: `A`,
headerBackTitle: 'A much too long text for back button from B to A',
- headerTruncatedBackTitle: `to A`
+ headerTruncatedBackTitle: `to A`,
}),
},
B: {
@@ -147,7 +147,7 @@ StackNavigator({
navigationOptions: () => ({
title: `B`,
}),
- }
+ },
});
```
@@ -217,8 +217,8 @@ Whether you can use gestures to dismiss this screen. Defaults to true on iOS, fa
Object to override the distance of touch start from the edge of the screen to recognize gestures. It takes the following properties:
-* `horizontal` - *number* - Distance for horizontal direction. Defaults to 25.
-* `vertical` - *number* - Distance for vertical direction. Defaults to 135.
+- `horizontal` - _number_ - Distance for horizontal direction. Defaults to 25.
+- `vertical` - _number_ - Distance for vertical direction. Defaults to 135.
#### `gestureDirection`
@@ -239,7 +239,7 @@ const Store = createStackNavigator({
The navigator component created by `createStackNavigator(...)` takes the following props:
-* `screenProps` - Pass down extra options to child screens, for example:
+- `screenProps` - Pass down extra options to child screens, for example:
```js
const SomeStack = createStackNavigator({
@@ -277,7 +277,7 @@ const ModalNavigator = createStackNavigator(
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
- screenInterpolator: sceneProps => {
+ screenInterpolator: (sceneProps) => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
@@ -306,17 +306,21 @@ Header transitions can also be configured using `headerLeftInterpolator`, `heade
We can't set the `StackNavigatorConfig`'s `mode` dynamically. Instead we are going to use a custom `transitionConfig` to render the specific transition we want - modal or card - on a screen by screen basis.
```js
-import { createStackNavigator, StackViewTransitionConfigs } from 'react-navigation';
+import {
+ createStackNavigator,
+ StackViewTransitionConfigs,
+} from 'react-navigation';
/* The screens you add to IOS_MODAL_ROUTES will have the modal transition. */
const IOS_MODAL_ROUTES = ['OptionsScreen'];
let dynamicModalTransition = (transitionProps, prevTransitionProps) => {
const isModal = IOS_MODAL_ROUTES.some(
- screenName =>
+ (screenName) =>
screenName === transitionProps.scene.route.routeName ||
- (prevTransitionProps && screenName === prevTransitionProps.scene.route.routeName)
- )
+ (prevTransitionProps &&
+ screenName === prevTransitionProps.scene.route.routeName)
+ );
return StackViewTransitionConfigs.defaultTransitionConfig(
transitionProps,
prevTransitionProps,
diff --git a/versioned_docs/version-3.x/status-bar.md b/versioned_docs/version-3.x/status-bar.md
index 217c96f7c66..af0e672ecf8 100644
--- a/versioned_docs/version-3.x/status-bar.md
+++ b/versioned_docs/version-3.x/status-bar.md
@@ -15,17 +15,12 @@ class Screen1 extends React.Component {
render() {
return (
-
-
- Light Screen
-
+
+ Light Screen
this.props.navigation.navigate('Screen2')}
- color={isAndroid ? "blue" : "#fff"}
+ color={isAndroid ? 'blue' : '#fff'}
/>
);
@@ -36,13 +31,8 @@ class Screen2 extends React.Component {
render() {
return (
-
-
- Dark Screen
-
+
+ Dark Screen
this.props.navigation.navigate('Screen1')}
@@ -54,16 +44,19 @@ class Screen2 extends React.Component {
```
```jsx
-export default createStackNavigator({
- Screen1: {
- screen: Screen1,
+export default createStackNavigator(
+ {
+ Screen1: {
+ screen: Screen1,
+ },
+ Screen2: {
+ screen: Screen2,
+ },
},
- Screen2: {
- screen: Screen2,
- },
-}, {
- headerMode: 'none',
-});
+ {
+ headerMode: 'none',
+ }
+);
```

@@ -97,9 +90,7 @@ class Screen2 extends React.Component {
render() {
return (
-
- Dark Screen
-
+ Dark Screen
this.props.navigation.navigate('Screen1')}
diff --git a/versioned_docs/version-3.x/tab-based-navigation.md b/versioned_docs/version-3.x/tab-based-navigation.md
index 9ab111c0a11..ffb9ad788d4 100644
--- a/versioned_docs/version-3.x/tab-based-navigation.md
+++ b/versioned_docs/version-3.x/tab-based-navigation.md
@@ -91,9 +91,9 @@ export default createBottomTabNavigator(
Let's dissect this:
-* `tabBarIcon` is a property on `navigationOptions`, so we know we can use it on our screen components, but in this case chose to put it in the `createBottomTabNavigator` configuration in order to centralize the icon configuration for convenience.
-* `tabBarIcon` is a function that is given the `focused` state, `tintColor`, and `horizontal` param, which is a boolean. If you take a peek further down in the configuration you will see `tabBarOptions` and `activeTintColor` and `inactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `tintColor` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active). The orientation state `horizontal` is `true` when the device is in landscape, otherwise is `false` for portrait.
-* Read the [full API reference](bottom-tab-navigator.md) for further information on `createBottomTabNavigator` configuration options.
+- `tabBarIcon` is a property on `navigationOptions`, so we know we can use it on our screen components, but in this case chose to put it in the `createBottomTabNavigator` configuration in order to centralize the icon configuration for convenience.
+- `tabBarIcon` is a function that is given the `focused` state, `tintColor`, and `horizontal` param, which is a boolean. If you take a peek further down in the configuration you will see `tabBarOptions` and `activeTintColor` and `inactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `tintColor` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active). The orientation state `horizontal` is `true` when the device is in landscape, otherwise is `false` for portrait.
+- Read the [full API reference](bottom-tab-navigator.md) for further information on `createBottomTabNavigator` configuration options.
## Add badges to icons
@@ -106,21 +106,25 @@ export default class IconWithBadge extends React.Component {
return (
- { badgeCount > 0 && (
-
- {badgeCount}
+ {badgeCount > 0 && (
+
+
+ {badgeCount}
+
)}
@@ -135,8 +139,8 @@ From UI perspective this component is ready to use, but you still need to find s
const HomeIconWithBadge = (props) => {
// You should pass down the badgeCount in some other ways like React Context API, Redux, MobX or event emitters.
return ;
-}
-export default HomeIconWithBadge
+};
+export default HomeIconWithBadge;
```
## Jumping between tabs
@@ -236,15 +240,17 @@ const SettingsStack = createStackNavigator({
Details: DetailsScreen,
});
-export default createAppContainer(createBottomTabNavigator(
- {
- Home: HomeStack,
- Settings: SettingsStack,
- },
- {
- /* Other configuration remains unchanged */
- }
-));
+export default createAppContainer(
+ createBottomTabNavigator(
+ {
+ Home: HomeStack,
+ Settings: SettingsStack,
+ },
+ {
+ /* Other configuration remains unchanged */
+ }
+ )
+);
```
→ Run this code
diff --git a/versioned_docs/version-3.x/themes.md b/versioned_docs/version-3.x/themes.md
index 7b862a7dff7..849c2906a96 100644
--- a/versioned_docs/version-3.x/themes.md
+++ b/versioned_docs/version-3.x/themes.md
@@ -71,7 +71,8 @@ function MyButton() {
return (
+ style={{ backgroundColor: theme === 'light' ? '#000' : '#fff' }}
+ >
Button!
@@ -112,7 +113,8 @@ class MyButton extends React.Component {
render() {
return (
+ style={{ backgroundColor: theme === 'light' ? '#000' : '#fff' }}
+ >
Button!
@@ -271,7 +273,8 @@ export default class AppContainer extends React.Component {
render() {
return (
+ value={{ theme: this.state.theme, toggleTheme: this.toggleTheme }}
+ >
);
@@ -282,7 +285,8 @@ class HomeScreen extends React.Component {
render() {
return (
+ style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}
+ >
{({ toggleTheme }) => (
@@ -352,7 +356,8 @@ class HomeScreen extends React.Component {
render() {
return (
+ style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}
+ >
{({ toggleTheme }) => (
@@ -380,7 +385,8 @@ export default class AppContainer extends React.Component {
render() {
return (
+ value={{ theme: this.state.theme, toggleTheme: this.toggleTheme }}
+ >
);
diff --git a/versioned_docs/version-3.x/web-support.md b/versioned_docs/version-3.x/web-support.md
index 29fa22d4ff1..b0383d9c341 100644
--- a/versioned_docs/version-3.x/web-support.md
+++ b/versioned_docs/version-3.x/web-support.md
@@ -21,8 +21,8 @@ This approach requires that you rebuild the navigation views for your app (at le
To set up a navigator in a React app, [(such as one created with create-react-app)](https://github.com/react-navigation/example-web):
```js
-import { createSwitchNavigator } from "@react-navigation/core";
-import { createBrowserApp } from "@react-navigation/web";
+import { createSwitchNavigator } from '@react-navigation/core';
+import { createBrowserApp } from '@react-navigation/web';
const MyNavigator = createSwitchNavigator(routes);
@@ -42,7 +42,7 @@ When the app is running, the default browser behavior will be blocked and a navi
To render a link to the "Profile" route:
```js
-
+
Jamie's Profile
```
@@ -56,8 +56,7 @@ You can alternatively provide an `action` prop to the `Link`, to specify the exa
You can use the `handleServerRequest` function to get the top-level navigation prop for your app, as well as the current title for this route.
```js
-expressApp.get("/*", (req, res) => {
-
+expressApp.get('/*', (req, res) => {
const { path, query } = req;
const { navigation, title, options } = handleServerRequest(
diff --git a/versioned_docs/version-3.x/with-navigation-focus.md b/versioned_docs/version-3.x/with-navigation-focus.md
index 8ab8d51e0ce..a8d73142585 100644
--- a/versioned_docs/version-3.x/with-navigation-focus.md
+++ b/versioned_docs/version-3.x/with-navigation-focus.md
@@ -6,7 +6,7 @@ sidebar_label: withNavigationFocus
`withNavigationFocus` is a higher order component which passes the `isFocused` prop into a wrapped component. It's useful if you need to use the focus state in the render function of your screen component or another component rendered somewhere inside of a screen.
-* `withNavigationFocus(Component)` returns a component.
+- `withNavigationFocus(Component)` returns a component.
## Example
diff --git a/versioned_docs/version-3.x/with-navigation.md b/versioned_docs/version-3.x/with-navigation.md
index 93c931e668b..3bfcfd8e421 100644
--- a/versioned_docs/version-3.x/with-navigation.md
+++ b/versioned_docs/version-3.x/with-navigation.md
@@ -17,7 +17,14 @@ import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
- return { this.props.navigation.goBack() }} />;
+ return (
+ {
+ this.props.navigation.goBack();
+ }}
+ />
+ );
}
}
diff --git a/versioned_docs/version-4.x/MST-integration.md b/versioned_docs/version-4.x/MST-integration.md
index 2ce8a8755f6..93e55fac08e 100644
--- a/versioned_docs/version-4.x/MST-integration.md
+++ b/versioned_docs/version-4.x/MST-integration.md
@@ -61,7 +61,7 @@ export const NavigationStore = types
}));
```
-Note that `userProfileScreenParams` is a simple model with a `user` entry, while `productDetailScreenParams` is a map of `ProductDetailScreenParams` model. The reason we chose this shape of data is that we only have a single user profile screen in our app which reads its params from `userProfileScreenParams`. `productDetailScreenParams` is a map because the app can have several product screens on a stack. Each screen points to a `Product` instance saved in the map. The keys into the map are the React Navigation [keys](navigation-key.md#usage-with-the-navigate-navigation-actionshtml-navigate-call): think of the `key` as of an identifier of the route.
+Note that `userProfileScreenParams` is a simple model with a `user` entry, while `productDetailScreenParams` is a map of `ProductDetailScreenParams` model. The reason we chose this shape of data is that we only have a single user profile screen in our app which reads its params from `userProfileScreenParams`. `productDetailScreenParams` is a map because the app can have several product screens on a stack. Each screen points to a `Product` instance saved in the map. The keys into the map are the React Navigation [keys](navigation-key.md#usage-with-the-navigate-call): think of the `key` as of an identifier of the route.
Your navigation store may also be just one map where for each screen (regardless if it is a product or user profile screen), we store its navigation params. This is the approach taken in the [sample app](https://github.com/vonovak/react-navigation-mst-demo).
diff --git a/versioned_docs/version-4.x/app-containers.md b/versioned_docs/version-4.x/app-containers.md
index 2732660712e..476b3c649e7 100644
--- a/versioned_docs/version-4.x/app-containers.md
+++ b/versioned_docs/version-4.x/app-containers.md
@@ -10,7 +10,9 @@ We've been taking `createAppContainer` for granted so far, so let's explain them
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
-const RootStack = createStackNavigator({ /* your routes here */ });
+const RootStack = createStackNavigator({
+ /* your routes here */
+});
const AppContainer = createAppContainer(RootStack);
// Now AppContainer is the main component for React to render
@@ -54,7 +56,7 @@ class App extends React.Component {
render() {
return (
{
+ ref={(nav) => {
this.navigator = nav;
}}
/>
diff --git a/versioned_docs/version-4.x/contributing.md b/versioned_docs/version-4.x/contributing.md
index faf347fc790..5472a1c0acd 100644
--- a/versioned_docs/version-4.x/contributing.md
+++ b/versioned_docs/version-4.x/contributing.md
@@ -32,7 +32,7 @@ And here are a few helpful resources to aid in getting started:
You can't write code without writing the occasional bug. Especially as React Navigation is moving quickly, bugs happen. When you think you've found one here's what to do:
1. Search the existing issues for one like what you're seeing. If you see one, add a 👍 reaction (please no +1 comments). Read through the comments and see if you can provide any more valuable information to the thread
-2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/4.x/.github/ISSUE_TEMPLATE.md).
+2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/v4.1.1/.github/ISSUE_TEMPLATE/bug_report.md).
Creating a high quality reproduction is critical. Without it we likely can't fix the bug and, in an ideal situation, you'll find out that it's not actually a bug of the library but simply done incorrectly in your project. Instant bug fix!
@@ -93,7 +93,7 @@ The libdef (located at `flow/react-navigation.js`) will need to be updated such
### Issue Template
-Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/4.x/.github/ISSUE_TEMPLATE.md) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
+Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/v4.1.1/.github/ISSUE_TEMPLATE/bug_report.md) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
Yes, it takes time and effort to complete the issue template. But that's the only way to ask high quality questions that actually get responses.
@@ -101,7 +101,7 @@ Would you rather take 1 minute to create an incomplete issue report and wait mon
### Pull Request Template
-Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/4.x/.github/PULL_REQUEST_TEMPLATE.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
+Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/v4.1.1/.github/PULL_REQUEST_TEMPLATE.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
### Forking the Repository
diff --git a/versioned_docs/version-4.x/custom-navigator-overview.md b/versioned_docs/version-4.x/custom-navigator-overview.md
index 97826743dd7..39699c3bda9 100644
--- a/versioned_docs/version-4.x/custom-navigator-overview.md
+++ b/versioned_docs/version-4.x/custom-navigator-overview.md
@@ -24,4 +24,4 @@ The navigators render application screens which are just React components.
To learn how to create screens, read about:
- [Screen `navigation` prop](navigation-prop.md) to allow the screen to dispatch navigation actions, such as opening another screen
-- Screen `navigationOptions` to customize how the screen gets presented by the navigator (e.g. [header title](stack-navigator.md#navigationoptions-used-by-stacknavigator), tab label)
+- Screen `navigationOptions` to customize how the screen gets presented by the navigator (e.g. [header title](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator), tab label)
diff --git a/versioned_docs/version-4.x/deep-linking.md b/versioned_docs/version-4.x/deep-linking.md
index 60536603b43..4576a34ca32 100644
--- a/versioned_docs/version-4.x/deep-linking.md
+++ b/versioned_docs/version-4.x/deep-linking.md
@@ -4,7 +4,7 @@ title: Deep linking
sidebar_label: Deep linking
---
-In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `mychat://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
+In this guide we will set up our app to handle external URIs. Let's suppose that we want a URI like `example://chat/Eric` to open our app and link straight into a chat screen for some user named "Eric".
## Configuration
@@ -66,12 +66,12 @@ const FriendsScreen = createStackNavigator({
## Set up with Expo projects
-First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `mychat` then a link to your app would be `mychat://`. The scheme only applies to standalone apps and you need to re-build the standalone app for the change to take effect. In the Expo client app you can deep link using `exp://ADDRESS:PORT` where `ADDRESS` is often `127.0.0.1` and `PORT` is often `19000` - the URL is printed when you run `expo start`. If you want to test with your custom scheme you will need to run `expo build:ios -t simulator` or `expo build:android` and install the resulting binaries in your emulators. You can register for a scheme in your `app.json` by adding a string under the scheme key:
+First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `example` then a link to your app would be `example://`. The scheme only applies to standalone apps and you need to re-build the standalone app for the change to take effect. In the Expo client app you can deep link using `exp://ADDRESS:PORT` where `ADDRESS` is often `127.0.0.1` and `PORT` is often `19000` - the URL is printed when you run `expo start`. If you want to test with your custom scheme you will need to run `expo build:ios -t simulator` or `expo build:android` and install the resulting binaries in your emulators. You can register for a scheme in your `app.json` by adding a string under the scheme key:
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -134,14 +134,14 @@ Next, let's configure our navigation container to extract the path from the app'
```js
const SimpleApp = createAppContainer(createStackNavigator({...}));
-const prefix = 'mychat://';
+const prefix = 'example://';
const MainApp = () => ;
```
### iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
@@ -159,7 +159,7 @@ In `SimpleApp/ios/SimpleApp/AppDelegate.m`:
In Xcode, open the project at `SimpleApp/ios/SimpleApp.xcodeproj`. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
Now you can press play in Xcode, or re-build on the command line:
@@ -170,10 +170,10 @@ react-native run-ios
To test the URI on the simulator, run the following:
```bash
-xcrun simctl openurl booted mychat://chat/Eric
+xcrun simctl openurl booted example://chat/Eric
```
-To test the URI on a real device, open Safari and type `mychat://chat/Eric`.
+To test the URI on a real device, open Safari and type `example://chat/Eric`.
### Android
@@ -196,7 +196,7 @@ In `SimpleApp/android/app/src/main/AndroidManifest.xml`, do these followings adj
-
+
```
@@ -210,7 +210,7 @@ react-native run-android
To test the intent handling in Android, run the following:
```bash
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/Eric" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/Eric" com.simpleapp
```
## Disable deep linking
diff --git a/versioned_docs/version-4.x/drawer-actions.md b/versioned_docs/version-4.x/drawer-actions.md
index 91dd2574ae8..c09626ede59 100644
--- a/versioned_docs/version-4.x/drawer-actions.md
+++ b/versioned_docs/version-4.x/drawer-actions.md
@@ -8,9 +8,9 @@ sidebar_label: DrawerActions
The following actions are supported:
-- [openDrawer](#openDrawer) - open the drawer
-- [closeDrawer](#closeDrawer) - close the drawer
-- [toggleDrawer](#toggleDrawer) - toggle the state, ie. switches from closed to open and vice versa
+- openDrawer - open the drawer
+- closeDrawer - close the drawer
+- toggleDrawer - toggle the state, ie. switches from closed to open and vice versa
### Usage
diff --git a/versioned_docs/version-4.x/header-buttons.md b/versioned_docs/version-4.x/header-buttons.md
index 3d218a8ceae..47466e9994d 100644
--- a/versioned_docs/version-4.x/header-buttons.md
+++ b/versioned_docs/version-4.x/header-buttons.md
@@ -90,4 +90,3 @@ Generally, this is what you want. But it's possible that in some circumstances t
- You can set buttons in the header through the `headerLeft` and `headerRight` properties in `navigationOptions`.
- The back button is fully customizable with `headerLeft`, but if you just want to change the title or image, there are other `navigationOptions` for that — `headerBackTitle`, `headerTruncatedBackTitle`, and `headerBackImage`.
-- [Full source of what we have built so far](#example/header-interaction).
diff --git a/versioned_docs/version-4.x/headers.md b/versioned_docs/version-4.x/headers.md
index a064dfbe26b..8b93bc3ff2f 100644
--- a/versioned_docs/version-4.x/headers.md
+++ b/versioned_docs/version-4.x/headers.md
@@ -230,11 +230,10 @@ class HomeScreen extends React.Component {
## Additional configuration
-You can read the full list of available `navigationOptions` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+You can read the full list of available `navigationOptions` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator).
## Summary
-- You can customize the header inside of the `navigationOptions` static property on your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+- You can customize the header inside of the `navigationOptions` static property on your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-for-screens-inside-of-the-navigator).
- The `navigationOptions` static property can be an object or a function. When it is a function, it is provided with an object with the `navigation` prop, `screenProps`, and `navigationOptions` on it.
- You can also specify shared `navigationOptions` in the stack navigator configuration when you initialize it. The static property takes precedence over that configuration.
-- [Full source of what we have built so far](#example/custom-header-title-component).
diff --git a/versioned_docs/version-4.x/hello-react-navigation.md b/versioned_docs/version-4.x/hello-react-navigation.md
index f52560019ad..e45acbff1b8 100644
--- a/versioned_docs/version-4.x/hello-react-navigation.md
+++ b/versioned_docs/version-4.x/hello-react-navigation.md
@@ -115,4 +115,3 @@ Now our stack has two _routes_, a `Home` route and a `Details` route. The `Home`
- `createStackNavigator` is a function that takes a route configuration object and an options object and returns a React component.
- The keys in the route configuration object are the route names and the values are the configuration for that route. The only required property on the configuration is the `screen` (the component to use for the route).
- To specify what the initial route in a stack is, provide an `initialRouteName` on the stack options object.
-- [Full source of what we have built so far](#example/hello-react-navigation-full).
diff --git a/versioned_docs/version-4.x/localization.md b/versioned_docs/version-4.x/localization.md
index 84e680a89be..34a7e6b53d6 100644
--- a/versioned_docs/version-4.x/localization.md
+++ b/versioned_docs/version-4.x/localization.md
@@ -41,7 +41,7 @@ export default class App extends React.Component {
locale: Localization.locale,
};
- setLocale = locale => {
+ setLocale = (locale) => {
this.setState({ locale });
};
diff --git a/versioned_docs/version-4.x/modal.md b/versioned_docs/version-4.x/modal.md
index e4119780951..fe31980e201 100644
--- a/versioned_docs/version-4.x/modal.md
+++ b/versioned_docs/version-4.x/modal.md
@@ -91,4 +91,3 @@ There are some important things to notice here:
- To change the type of transition on a stack navigator you can use the `mode` configuration. When set to `modal`, all screens animate-in from bottom to top rather than right to left. This applies to that entire stack navigator, so to use right to left transitions on other screens, we add another navigation stack with the default configuration.
- `this.props.navigation.navigate` traverses up the navigator tree to find a navigator that can handle the `navigate` action.
-- [Full source of what we have built so far](#example/full-screen-modal)
diff --git a/versioned_docs/version-4.x/navigating-without-navigation-prop.md b/versioned_docs/version-4.x/navigating-without-navigation-prop.md
index 053ab404574..1e87609e130 100644
--- a/versioned_docs/version-4.x/navigating-without-navigation-prop.md
+++ b/versioned_docs/version-4.x/navigating-without-navigation-prop.md
@@ -26,7 +26,7 @@ export default class App extends React.Component {
render() {
return (
{
+ ref={(navigatorRef) => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
diff --git a/versioned_docs/version-4.x/navigating.md b/versioned_docs/version-4.x/navigating.md
index f12c9ddf8e6..da79fd58e5e 100644
--- a/versioned_docs/version-4.x/navigating.md
+++ b/versioned_docs/version-4.x/navigating.md
@@ -134,4 +134,3 @@ Another common requirement is to be able to go back _multiple_ screens -- for ex
- The header bar will automatically show a back button, but you can programmatically go back by calling `this.props.navigation.goBack()`. On Android, the hardware back button just works as expected.
- You can go back to an existing screen in the stack with `this.props.navigation.navigate('RouteName')`, and you can go back to the first screen in the stack with `this.props.navigation.popToTop()`.
- The `navigation` prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).
-- [Full source of what we have built so far](#example/go-back).
diff --git a/versioned_docs/version-4.x/navigation-actions.md b/versioned_docs/version-4.x/navigation-actions.md
index cf196c9c287..f8268ae5ba2 100644
--- a/versioned_docs/version-4.x/navigation-actions.md
+++ b/versioned_docs/version-4.x/navigation-actions.md
@@ -15,7 +15,6 @@ The following actions are supported:
- [Navigate](#navigate) - Navigate to another route
- [Back](#back) - Go back to previous state
- [Set Params](#setparams) - Set Params for given route
-- [Init](#init) - Used to initialize first state if state is undefined
For actions specific to a StackNavigator, see [StackActions](stack-actions.md).
For actions specific to a switch-based navigators such as TabNavigator, see [SwitchActions](switch-actions.md).
diff --git a/versioned_docs/version-4.x/navigation-events.md b/versioned_docs/version-4.x/navigation-events.md
index b4a25580490..a258d361e33 100644
--- a/versioned_docs/version-4.x/navigation-events.md
+++ b/versioned_docs/version-4.x/navigation-events.md
@@ -14,7 +14,7 @@ sidebar_label: NavigationEvents
- `onWillBlur` - event listener
- `onDidBlur` - event listener
-The event listener is the same as the imperative [`navigation.addListener(...)`](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle) API.
+The event listener is the same as the imperative [`navigation.addListener(...)`](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle) API.
### Example
@@ -26,10 +26,10 @@ import { NavigationEvents } from 'react-navigation';
const MyScreen = () => (
console.log('will focus', payload)}
- onDidFocus={payload => console.log('did focus', payload)}
- onWillBlur={payload => console.log('will blur', payload)}
- onDidBlur={payload => console.log('did blur', payload)}
+ onWillFocus={(payload) => console.log('will focus', payload)}
+ onDidFocus={(payload) => console.log('did focus', payload)}
+ onWillBlur={(payload) => console.log('will blur', payload)}
+ onDidBlur={(payload) => console.log('did blur', payload)}
/>
{/*
Your view code
diff --git a/versioned_docs/version-4.x/navigation-key.md b/versioned_docs/version-4.x/navigation-key.md
index 8655464c291..941c6189082 100644
--- a/versioned_docs/version-4.x/navigation-key.md
+++ b/versioned_docs/version-4.x/navigation-key.md
@@ -17,14 +17,14 @@ If, however, you want to push several instances of the same route, you can do so
> Note: the behavior of `navigate` without a `key` is significantly different in the 1.x series of releases. Read more about it [here](https://gist.github.com/vonovak/ef72f5efe1d36742de8968ff6a708985).
-### Usage with [`reset`](navigation-actions.md#reset)
+### Usage with [`reset`](stack-actions.md#reset)
When resetting, `key` is also optional and can be a string or `null`. If set, the navigator with the given key will reset. If `null`, the root navigator will reset. You can obtain a route's navigator key by calling `this.props.navigation.dangerouslyGetParent().state.key`. Reason why the function is called `dangerouslyGetParent` is to warn developers against overusing it to eg. get parent of parent and other hard-to-follow patterns.
-### Usage with [`replace`](navigation-actions.md#replace)
+### Usage with [`replace`](stack-actions.md#replace)
With the `replace` navigation action, `key` is a required parameter used for identifying the route to be replaced. If you use the helper function `this.props.navigation.replace`, we will automatically substitute the key of the current route.
### Usage with `goBack`
-Please refer to the [`goBack docs`](navigation-prop.md#goback-close-the-active-screen-and-move-back) for a detailed explanation.
+Please refer to the [`goBack docs`](navigation-prop.md#goback---close-the-active-screen-and-move-back) for a detailed explanation.
diff --git a/versioned_docs/version-4.x/navigation-lifecycle.md b/versioned_docs/version-4.x/navigation-lifecycle.md
index dc72def1d0e..f40ec969cad 100644
--- a/versioned_docs/version-4.x/navigation-lifecycle.md
+++ b/versioned_docs/version-4.x/navigation-lifecycle.md
@@ -20,7 +20,7 @@ When going back from `B` to `A`, `componentWillUnmount` of `B` is called, but `c
Now that we understand how React lifecycle methods work in React Navigation, let's answer the question we asked at the beginning: "How do we find out that a user is leaving it or coming back to it?"
-React Navigation emits events to screen components that subscribe to them. There are four different events that you can subscribe to: `willFocus`, `willBlur`, `didFocus` and `didBlur`. Read more about them in the [API reference](navigation-prop.md#addlistener-subscribe-to-updates-to-navigation-lifecycle).
+React Navigation emits events to screen components that subscribe to them. There are four different events that you can subscribe to: `willFocus`, `willBlur`, `didFocus` and `didBlur`. Read more about them in the [API reference](navigation-prop.md#addlistener---subscribe-to-updates-to-navigation-lifecycle).
Many of your use cases may be covered with the [`withNavigationFocus` higher-order-component](with-navigation-focus.md), the [` ` component](navigation-events.md), or the [useFocusState hook](https://github.com/react-navigation/hooks#usefocusstate).
diff --git a/versioned_docs/version-4.x/navigation-options-resolution.md b/versioned_docs/version-4.x/navigation-options-resolution.md
index 0ad9065f545..c29573edfa4 100644
--- a/versioned_docs/version-4.x/navigation-options-resolution.md
+++ b/versioned_docs/version-4.x/navigation-options-resolution.md
@@ -126,7 +126,7 @@ const HomeStack = createStackNavigator(
→ Run this code
-# getActiveChildNavigationOptions
+## getActiveChildNavigationOptions
If you would like to get the `navigationOptions` from the active child of a navigator, you can do that with `getActiveChildNavigationOptions`. This makes it possible for you to set the `tabBarLabel` directly on a screen inside of a stack that is inside of a tab, for example.
@@ -157,11 +157,11 @@ const HomeStack = createStackNavigator(
→ Run this code
-# **Note**: the navigationOptions property vs navigator configuration
+## **Note**: the navigationOptions property vs navigator configuration
Navigators are initialized with `create*Navigator(routeConfig, navigatorConfig)`. Inside of `navigatorConfig` we can add a `defaultNavigationOptions` property. These `defaultNavigationOptions` are the default options for screens within that navigator ([read more about sharing common navigationOptions](headers.md#sharing-common-navigationoptions-across-screens)), they do not refer to the `navigationOptions` for that navigator — as we have seen above, we set the `navigationOptions` property directly on the navigator for that use case.
-# A stack contains a tab navigator and you want to set the title on the stack header
+## A stack contains a tab navigator and you want to set the title on the stack header
Imagine the following configuration:
@@ -230,7 +230,7 @@ Using this configuration, the `headerTitle` or `title` from `navigationOptions`
Additionally, you can push new screens to the feed and profile stacks without hiding the tab bar by adding more routes to those stacks. If you want to push screens on top of the tab bar, then you can add them to the `AppNavigator` stack.
-# A tab navigator contains a stack and you want to hide the tab bar on specific screens
+## A tab navigator contains a stack and you want to hide the tab bar on specific screens
Similar to the example above where a stack contains a tab navigator, we can solve this in two ways: add `navigationOptions` to our tab navigator to set the tab bar to hidden depending on which route is active in the child stack, or we can move the tab navigator inside of the stack.
@@ -300,7 +300,7 @@ const AppNavigator = createSwitchNavigator({
});
```
-# A drawer has a stack inside of it and you want to lock the drawer on certain screens
+## A drawer has a stack inside of it and you want to lock the drawer on certain screens
This is conceptually identical to having a tab with a stack inside of it (read that above if you have not already), where you want to hide the tab bar on certain screens. The only difference is that rather than using `tabBarVisible` you will use `drawerLockMode`.
diff --git a/versioned_docs/version-4.x/navigation-prop.md b/versioned_docs/version-4.x/navigation-prop.md
index a28aef89344..03f4db13293 100644
--- a/versioned_docs/version-4.x/navigation-prop.md
+++ b/versioned_docs/version-4.x/navigation-prop.md
@@ -135,7 +135,7 @@ Example:
```javascript
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
- payload => {
+ (payload) => {
console.debug('didBlur', payload);
}
);
diff --git a/versioned_docs/version-4.x/params.md b/versioned_docs/version-4.x/params.md
index f3d239d3a50..d959b7fbe47 100644
--- a/versioned_docs/version-4.x/params.md
+++ b/versioned_docs/version-4.x/params.md
@@ -74,4 +74,3 @@ class DetailsScreen extends React.Component {
- `navigate` and `push` accept an optional second argument to let you pass parameters to the route you are navigating to. For example: `this.props.navigation.navigate('RouteName', {paramName: 'value'})`.
- You can read the params through `this.props.navigation.getParam`
- As an alternative to `getParam`, you may use `this.props.navigation.state.params`. It is `null` if no parameters are specified.
-- [Full source of what we have built so far](#example/passing-params).
diff --git a/versioned_docs/version-4.x/redux-integration.md b/versioned_docs/version-4.x/redux-integration.md
index d26c9bffd00..e5b707b6172 100644
--- a/versioned_docs/version-4.x/redux-integration.md
+++ b/versioned_docs/version-4.x/redux-integration.md
@@ -43,7 +43,7 @@ class Count extends React.Component {
}
}
-let CountContainer = connect(state => ({ value: state.count }))(Count);
+let CountContainer = connect((state) => ({ value: state.count }))(Count);
class Counter extends React.Component {
static navigationOptions = {
diff --git a/versioned_docs/version-4.x/screen-tracking.md b/versioned_docs/version-4.x/screen-tracking.md
index 454f3f4ab27..39a7de213e7 100644
--- a/versioned_docs/version-4.x/screen-tracking.md
+++ b/versioned_docs/version-4.x/screen-tracking.md
@@ -39,7 +39,7 @@ export default () => (
// change the tracker here to use other Mobile analytics SDK.
await analytics().logScreenView({
screen_name: currentRouteName,
- screen_class: currentRouteName
+ screen_class: currentRouteName,
});
}
}}
diff --git a/versioned_docs/version-4.x/stack-navigator-1.0.md b/versioned_docs/version-4.x/stack-navigator-1.0.md
index 010afe69893..93b500daa42 100644
--- a/versioned_docs/version-4.x/stack-navigator-1.0.md
+++ b/versioned_docs/version-4.x/stack-navigator-1.0.md
@@ -274,7 +274,7 @@ const ModalNavigator = createStackNavigator(
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
- screenInterpolator: sceneProps => {
+ screenInterpolator: (sceneProps) => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
@@ -313,7 +313,7 @@ const IOS_MODAL_ROUTES = ['OptionsScreen'];
let dynamicModalTransition = (transitionProps, prevTransitionProps) => {
const isModal = IOS_MODAL_ROUTES.some(
- screenName =>
+ (screenName) =>
screenName === transitionProps.scene.route.routeName ||
(prevTransitionProps &&
screenName === prevTransitionProps.scene.route.routeName)
diff --git a/versioned_docs/version-4.x/stack-navigator.md b/versioned_docs/version-4.x/stack-navigator.md
index 0b870e2e33a..930d90dff2a 100644
--- a/versioned_docs/version-4.x/stack-navigator.md
+++ b/versioned_docs/version-4.x/stack-navigator.md
@@ -69,8 +69,8 @@ Visual options:
- Prevents last inactive screen from being detached so that it stays visible underneath the active screen
- Make the screens slide in from the bottom on iOS which is a common iOS pattern.
- `headerMode` - Specifies how the header should be rendered:
- - `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
- - `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
+ - `float` - The header is rendered above the screen and animates independently of the screen. This is default on iOS for non-modals.
+ - `screen` - The header is rendered as part of the screen and animates together with the screen. This is default on other platforms.
- `none` - No header will be rendered.
- `keyboardHandlingEnabled` - If `false`, the on screen keyboard will NOT automatically dismiss when navigating to a new screen. Defaults to `true`.
@@ -97,8 +97,8 @@ header: ({ scene, previous, navigation }) => {
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
- ? options.title
- : scene.route.routeName;
+ ? options.title
+ : scene.route.routeName;
return (
{
+const HomeIconWithBadge = (props) => {
// You should pass down the badgeCount in some other ways like React Context API, Redux, MobX or event emitters.
return ;
};
diff --git a/versioned_docs/version-4.x/themes.md b/versioned_docs/version-4.x/themes.md
index e8819a9700e..7c92af05888 100644
--- a/versioned_docs/version-4.x/themes.md
+++ b/versioned_docs/version-4.x/themes.md
@@ -46,8 +46,8 @@ export default () => {
- )
-}
+ );
+};
```
If the version of React Native you are using doesn't support hooks yet, you can use the `Appearance.addChangeListener(cb)` and `Appearance.getColorScheme()` functions as described in the [usage section of the README](https://github.com/expo/react-native-appearance#usage).
@@ -91,10 +91,13 @@ import { ThemeContext } from 'react-navigation';
function MyButton() {
return (
- {theme => (
+ {(theme) => (
- Button!
+ style={{ backgroundColor: theme === 'light' ? '#000' : '#fff' }}
+ >
+
+ Button!
+
)}
@@ -341,10 +344,10 @@ Okay, that's a lot of code. There isn't much going on here aside from passing th
A regrettable limitation of the current implementation of `navigationOptions` is that we are unable to access React context for use in properties such as `headerStyle` and `headerTintColor`. We can and should use them in properties that access React components, for example in `headerRight` we could provide a component like `ThemedHeaderButton`. To apply the theme to other properties we need to use `screenProps`.
```jsx
-import {
+import {
createAppContainer,
createStackNavigator,
- ThemeContext
+ ThemeContext,
} from 'react-navigation';
class HomeScreen extends React.Component {
@@ -413,7 +416,7 @@ import {
createStackNavigator,
createBottomTabNavigator,
BottomTabBar,
- ThemeContext
+ ThemeContext,
} from 'react-navigation';
const ThemeConstants = {
diff --git a/versioned_docs/version-4.x/typescript.md b/versioned_docs/version-4.x/typescript.md
index 45e3f8d8e5d..88d4c8e2be2 100644
--- a/versioned_docs/version-4.x/typescript.md
+++ b/versioned_docs/version-4.x/typescript.md
@@ -98,10 +98,9 @@ type Params = { userId: string };
type ScreenProps = { language: string };
-const ProfileScreen: NavigationStackScreenComponent<
- Params,
- ScreenProps
-> = props => {
+const ProfileScreen: NavigationStackScreenComponent = (
+ props
+) => {
// ...
};
diff --git a/versioned_docs/version-4.x/web-support.md b/versioned_docs/version-4.x/web-support.md
index 29fa22d4ff1..b0383d9c341 100644
--- a/versioned_docs/version-4.x/web-support.md
+++ b/versioned_docs/version-4.x/web-support.md
@@ -21,8 +21,8 @@ This approach requires that you rebuild the navigation views for your app (at le
To set up a navigator in a React app, [(such as one created with create-react-app)](https://github.com/react-navigation/example-web):
```js
-import { createSwitchNavigator } from "@react-navigation/core";
-import { createBrowserApp } from "@react-navigation/web";
+import { createSwitchNavigator } from '@react-navigation/core';
+import { createBrowserApp } from '@react-navigation/web';
const MyNavigator = createSwitchNavigator(routes);
@@ -42,7 +42,7 @@ When the app is running, the default browser behavior will be blocked and a navi
To render a link to the "Profile" route:
```js
-
+
Jamie's Profile
```
@@ -56,8 +56,7 @@ You can alternatively provide an `action` prop to the `Link`, to specify the exa
You can use the `handleServerRequest` function to get the top-level navigation prop for your app, as well as the current title for this route.
```js
-expressApp.get("/*", (req, res) => {
-
+expressApp.get('/*', (req, res) => {
const { path, query } = req;
const { navigation, title, options } = handleServerRequest(
diff --git a/versioned_docs/version-4.x/with-navigation.md b/versioned_docs/version-4.x/with-navigation.md
index 420dc44d0d7..b90addeabd0 100644
--- a/versioned_docs/version-4.x/with-navigation.md
+++ b/versioned_docs/version-4.x/with-navigation.md
@@ -42,5 +42,5 @@ export default withNavigation(MyBackButton);
export default withNavigation(MyBackButton);
// MyNavBar.ts
- (this.backButton = elem)} />;
+ (this.backButton = elem)} />;
```
diff --git a/versioned_docs/version-5.x/auth-flow.md b/versioned_docs/version-5.x/auth-flow.md
index 9cb14f77f99..f1285f551be 100755
--- a/versioned_docs/version-5.x/auth-flow.md
+++ b/versioned_docs/version-5.x/auth-flow.md
@@ -37,7 +37,7 @@ isSignedIn ? (
>
-)
+);
```
When we define screens like this, when `isSignedIn` is `true`, React Navigation will only see the `Home`, `Profile` and `Settings` screens, and when it's `false`, React Navigation will see the `SignIn` and `SignUp` screens. This makes it impossible to navigate to the `Home`, `Profile` and `Settings` screens when the user is not signed in, and to `SignIn` and `SignUp` screens when the user is signed in.
@@ -207,7 +207,7 @@ export default function App({ navigation }) {
const authContext = React.useMemo(
() => ({
- signIn: async data => {
+ signIn: async (data) => {
// In a production app, we need to send some data (usually username, password) to server and get a token
// We will also need to handle errors if sign in failed
// After getting token, we need to persist the token using `SecureStore`
@@ -216,7 +216,7 @@ export default function App({ navigation }) {
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
},
signOut: () => dispatch({ type: 'SIGN_OUT' }),
- signUp: async data => {
+ signUp: async (data) => {
// In a production app, we need to send user data to server and get a token
// We will also need to handle errors if sign up failed
// After getting token, we need to persist the token using `SecureStore`
diff --git a/versioned_docs/version-5.x/bottom-tab-navigator.md b/versioned_docs/version-5.x/bottom-tab-navigator.md
index 5085d2412b0..99aefc35a01 100755
--- a/versioned_docs/version-5.x/bottom-tab-navigator.md
+++ b/versioned_docs/version-5.x/bottom-tab-navigator.md
@@ -6,11 +6,9 @@ sidebar_label: Bottom Tabs
A simple tab bar on the bottom of the screen that lets you switch between different routes. Routes are lazily initialized -- their screen components are not mounted until they are first focused.
-
-
-
-
-
+
+
+
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/bottom-tabs):
@@ -242,7 +240,9 @@ Style object for the tab bar. You can configure styles such as background color
To show your screen under the tab bar, you can set the `position` style to absolute:
```js
-style: { position: 'absolute' }
+style: {
+ position: 'absolute';
+}
```
You also might need to add a bottom margin to your content if you have a absolutely positioned tab bar. React Navigation won't do it automatically.
diff --git a/versioned_docs/version-5.x/configuring-links.md b/versioned_docs/version-5.x/configuring-links.md
index 4542bece964..01ed72fd7b3 100644
--- a/versioned_docs/version-5.x/configuring-links.md
+++ b/versioned_docs/version-5.x/configuring-links.md
@@ -106,7 +106,7 @@ const config = {
};
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config,
};
@@ -616,7 +616,7 @@ Example:
```js
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Chat: 'feed/:sort',
diff --git a/versioned_docs/version-5.x/contributing.md b/versioned_docs/version-5.x/contributing.md
index aa31a3cb0b6..f90dd750538 100755
--- a/versioned_docs/version-5.x/contributing.md
+++ b/versioned_docs/version-5.x/contributing.md
@@ -15,23 +15,9 @@ Here are some of the ways to contribute to the project:
- [Bug Fixes](#bug-fixes)
- [Suggesting a Feature](#suggesting-a-feature)
- [Big Pull Requests](#big-pull-requests)
-- [Information](#information)
- - [Issue Template](#issue-template)
- - [Pull Request Template](#pull-request-template)
- - [Forking the Repository](#forking-the-repository)
- - [Code Review Guidelines](#code-review-guidelines)
- - [Run the Example App](#run-the-example-app)
- - [Run Tests](#run-tests)
And here are a few helpful resources to aid in getting started:
-- [Contributing](#contributing)
- - [Reporting Bugs](#reporting-bugs)
- - [Improving the Documentation](#improving-the-documentation)
- - [Responding to Issues](#responding-to-issues)
- - [Bug Fixes](#bug-fixes)
- - [Suggesting a Feature](#suggesting-a-feature)
- - [Big Pull Requests](#big-pull-requests)
- [Information](#information)
- [Issue Template](#issue-template)
- [Pull Request Template](#pull-request-template)
@@ -47,7 +33,7 @@ And here are a few helpful resources to aid in getting started:
You can't write code without writing the occasional bug. Especially as React Navigation is moving quickly, bugs happen. When you think you've found one here's what to do:
1. Search the existing issues for one like what you're seeing. If you see one, add a 👍 reaction (please no +1 comments). Read through the comments and see if you can provide any more valuable information to the thread
-2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE.md).
+2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/%40react-navigation/core%405.14.4/.github/ISSUE_TEMPLATE/bug-report.md).
Creating a high quality reproduction is critical. Without it we likely can't fix the bug and, in an ideal situation, you'll find out that it's not actually a bug of the library but simply done incorrectly in your project. Instant bug fix!
@@ -96,7 +82,7 @@ The reason we want to do this is to save everyone time. Maybe that feature alrea
### Issue Template
-Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE.md) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
+Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/%40react-navigation/core%405.14.4/.github/ISSUE_TEMPLATE/bug-report.md) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
Yes, it takes time and effort to complete the issue template. But that's the only way to ask high quality questions that actually get responses.
@@ -104,7 +90,7 @@ Would you rather take 1 minute to create an incomplete issue report and wait mon
### Pull Request Template
-Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/main/.github/PULL_REQUEST.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
+Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/%40react-navigation/core%405.14.4/.github/PULL_REQUEST.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
### Forking the Repository
diff --git a/versioned_docs/version-5.x/custom-routers.md b/versioned_docs/version-5.x/custom-routers.md
index 7ee96cfb149..8dc1d1b8cc1 100755
--- a/versioned_docs/version-5.x/custom-routers.md
+++ b/versioned_docs/version-5.x/custom-routers.md
@@ -155,7 +155,7 @@ Let's say you want to add a custom action to clear the history:
```js
import { TabRouter } from '@react-navigation/native';
-const MyTabRouter = options => {
+const MyTabRouter = (options) => {
const router = TabRouter(options);
return {
@@ -191,7 +191,7 @@ Sometimes you may want to prevent some navigation activity, depending on your ro
```js
import { StackRouter } from '@react-navigation/native';
-const MyStackRouter = options => {
+const MyStackRouter = (options) => {
const router = StackRouter(options);
return {
diff --git a/versioned_docs/version-5.x/deep-linking.md b/versioned_docs/version-5.x/deep-linking.md
index 3bbc8115677..bbc447119a3 100755
--- a/versioned_docs/version-5.x/deep-linking.md
+++ b/versioned_docs/version-5.x/deep-linking.md
@@ -15,12 +15,12 @@ Below, we'll go through required configurations for each platform so that the de
## Set up with Expo projects
-First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `mychat` then a link to your app would be `mychat://`. The scheme only applies to standalone apps and you need to re-build the standalone app for the change to take effect. In the Expo client app you can deep link using `exp://ADDRESS:PORT` where `ADDRESS` is often `127.0.0.1` and `PORT` is often `19000` - the URL is printed when you run `expo start`. If you want to test with your custom scheme you will need to run `expo build:ios -t simulator` or `expo build:android` and install the resulting binaries in your emulators. You can register for a scheme in your `app.json` by adding a string under the scheme key:
+First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `example` then a link to your app would be `example://`. The scheme only applies to standalone apps and you need to re-build the standalone app for the change to take effect. In the Expo client app you can deep link using `exp://ADDRESS:PORT` where `ADDRESS` is often `127.0.0.1` and `PORT` is often `19000` - the URL is printed when you run `expo start`. If you want to test with your custom scheme you will need to run `expo build:ios -t simulator` or `expo build:android` and install the resulting binaries in your emulators. You can register for a scheme in your `app.json` by adding a string under the scheme key:
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -143,7 +143,7 @@ Read the [Expo linking guide](https://docs.expo.io/versions/latest/guides/linkin
### iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
You'll need to link `RCTLinking` to your project by following the steps described here. To be able to listen to incoming app links, you'll need to add the following lines to `SimpleApp/ios/SimpleApp/AppDelegate.m`.
@@ -192,11 +192,11 @@ If your app is using Universal Links, you'll need to add the following code as w
Now you need to add the scheme to your project configuration.
-The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add mychat --ios`.
+The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add example --ios`.
If you want to do it manually, open the project at `SimpleApp/ios/SimpleApp.xcodeproj` in Xcode. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
Now you can press play in Xcode, or re-build on the command line:
@@ -207,22 +207,22 @@ npx react-native run-ios
To test the URI on the simulator, run the following:
```bash
-npx uri-scheme open mychat://chat/jane --ios
+npx uri-scheme open example://chat/jane --ios
```
or use `xcrun` directly:
```bash
-xcrun simctl openurl booted mychat://chat/jane
+xcrun simctl openurl booted example://chat/jane
```
-To test the URI on a real device, open Safari and type `mychat://chat/jane`.
+To test the URI on a real device, open Safari and type `example://chat/jane`.
### Android
To configure the external linking in Android, you can create a new intent in the manifest.
-The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add mychat --android`.
+The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add example --android`.
If you want to add it manually, open up `SimpleApp/android/app/src/main/AndroidManifest.xml`, and make the following adjustments:
@@ -241,7 +241,7 @@ If you want to add it manually, open up `SimpleApp/android/app/src/main/AndroidM
-
+
```
@@ -255,13 +255,13 @@ react-native run-android
To test the intent handling in Android, run the following:
```bash
-npx uri-scheme open mychat://chat/jane --android
+npx uri-scheme open example://chat/jane --android
```
or use `adb` directly:
```bash
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/jane" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/jane" com.simpleapp
```
## Hybrid React Native and native iOS Applications (skip for React-Native-only projects)
diff --git a/versioned_docs/version-5.x/devtools.md b/versioned_docs/version-5.x/devtools.md
index c922dfb2b84..1d348e320c5 100644
--- a/versioned_docs/version-5.x/devtools.md
+++ b/versioned_docs/version-5.x/devtools.md
@@ -26,7 +26,10 @@ To use the hook, import it and pass a `ref` to the `NavigationContainer` as its
```js
import * as React from 'react';
-import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
import { useReduxDevToolsExtension } from '@react-navigation/devtools';
export default function App() {
diff --git a/versioned_docs/version-5.x/drawer-based-navigation.md b/versioned_docs/version-5.x/drawer-based-navigation.md
index 1e30e0192ba..10585dcfc6f 100755
--- a/versioned_docs/version-5.x/drawer-based-navigation.md
+++ b/versioned_docs/version-5.x/drawer-based-navigation.md
@@ -6,11 +6,9 @@ sidebar_label: Drawer navigation
Common pattern in navigation is to use drawer from left (sometimes right) side for navigating between screens.
-
-
-
-
-
+
+
+
Before continuing, first install [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer):
diff --git a/versioned_docs/version-5.x/drawer-navigator.md b/versioned_docs/version-5.x/drawer-navigator.md
index 0644f0db848..1d072165804 100755
--- a/versioned_docs/version-5.x/drawer-navigator.md
+++ b/versioned_docs/version-5.x/drawer-navigator.md
@@ -6,11 +6,9 @@ sidebar_label: Drawer
Component that renders a navigation drawer which can be opened and closed via gestures.
-
-
-
-
-
+
+
+
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer):
@@ -398,8 +396,8 @@ header: ({ scene }) => {
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
- ? options.title
- : scene.route.name;
+ ? options.title
+ : scene.route.name;
return (
{
- const unsubscribe = API.subscribe(userId, user => setUser(data));
+ const unsubscribe = API.subscribe(userId, (user) => setUser(data));
return () => unsubscribe();
}, [userId])
diff --git a/versioned_docs/version-5.x/header-buttons.md b/versioned_docs/version-5.x/header-buttons.md
index 5e553cdf16c..f1eaa268368 100755
--- a/versioned_docs/version-5.x/header-buttons.md
+++ b/versioned_docs/version-5.x/header-buttons.md
@@ -20,7 +20,7 @@ function StackScreen() {
name="Home"
component={HomeScreen}
options={{
- headerTitle: props => ,
+ headerTitle: (props) => ,
headerRight: () => (
alert('This is a button!')}
@@ -53,7 +53,7 @@ function StackScreen() {
name="Home"
component={HomeScreen}
options={({ navigation, route }) => ({
- headerTitle: props => ,
+ headerTitle: (props) => ,
})}
/>
@@ -66,7 +66,7 @@ function HomeScreen({ navigation }) {
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
- setCount(c => c + 1)} title="Update count" />
+ setCount((c) => c + 1)} title="Update count" />
),
});
}, [navigation]);
diff --git a/versioned_docs/version-5.x/headers.md b/versioned_docs/version-5.x/headers.md
index d702cb9b70a..bd4501e6dea 100755
--- a/versioned_docs/version-5.x/headers.md
+++ b/versioned_docs/version-5.x/headers.md
@@ -166,7 +166,7 @@ function StackScreen() {
}}
+ options={{ headerTitle: (props) => }}
/>
);
@@ -177,10 +177,10 @@ function StackScreen() {
## Additional configuration
-You can read the full list of available `options` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+You can read the full list of available `options` for screens inside of a stack navigator in the [`createStackNavigator` reference](stack-navigator.md#options).
## Summary
-- You can customize the header inside of the `options` prop of your screen components. Read the full list of options [in the API reference](stack-navigator.md#navigationoptions-used-by-stacknavigator).
+- You can customize the header inside of the `options` prop of your screen components. Read the full list of options [in the API reference](stack-navigator.md#options).
- The `options` prop can be an object or a function. When it is a function, it is provided with an object with the `navigation` and `route` prop.
- You can also specify shared `screenOptions` in the stack navigator configuration when you initialize it. The prop takes precedence over that configuration.
diff --git a/versioned_docs/version-5.x/hello-react-navigation.md b/versioned_docs/version-5.x/hello-react-navigation.md
index f816703f8c9..22c55b7fa96 100755
--- a/versioned_docs/version-5.x/hello-react-navigation.md
+++ b/versioned_docs/version-5.x/hello-react-navigation.md
@@ -127,7 +127,7 @@ Sometimes we might want to pass additional props to a screen. We can do that wit
```js
- {props => }
+ {(props) => }
```
diff --git a/versioned_docs/version-5.x/material-top-tab-navigator.md b/versioned_docs/version-5.x/material-top-tab-navigator.md
index cb8694c07e1..448ce3555af 100755
--- a/versioned_docs/version-5.x/material-top-tab-navigator.md
+++ b/versioned_docs/version-5.x/material-top-tab-navigator.md
@@ -8,11 +8,9 @@ A material-design themed tab bar on the top of the screen that lets you switch b
This wraps [`react-native-tab-view`](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view).
-
-
-
-
-
+
+
+
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/material-top-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/material-top-tabs):
@@ -351,7 +349,7 @@ To prevent the default behavior, you can call `event.preventDefault`:
```js
React.useEffect(() => {
- const unsubscribe = navigation.addListener('tabPress', e => {
+ const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
@@ -371,7 +369,7 @@ Example:
```js
React.useEffect(() => {
- const unsubscribe = navigation.addListener('tabLongPress', e => {
+ const unsubscribe = navigation.addListener('tabLongPress', (e) => {
// Do something
});
diff --git a/versioned_docs/version-5.x/navigating-without-navigation-prop.md b/versioned_docs/version-5.x/navigating-without-navigation-prop.md
index 325eb4cd096..85ac552d8f0 100755
--- a/versioned_docs/version-5.x/navigating-without-navigation-prop.md
+++ b/versioned_docs/version-5.x/navigating-without-navigation-prop.md
@@ -88,7 +88,7 @@ import { navigationRef, isReadyRef } from './RootNavigation';
export default function App() {
React.useEffect(() => {
return () => {
- isReadyRef.current = false
+ isReadyRef.current = false;
};
}, []);
diff --git a/versioned_docs/version-5.x/navigating.md b/versioned_docs/version-5.x/navigating.md
index 15597689572..f7ee3783a5a 100755
--- a/versioned_docs/version-5.x/navigating.md
+++ b/versioned_docs/version-5.x/navigating.md
@@ -91,11 +91,9 @@ Let's suppose that we actually _want_ to add another details screen. This is pre
/>
```
-
-
-
-
-
+
+
+
Each time you call `push` we add a new route to the navigation stack. When you call `navigate` it first tries to find an existing route with that name, and only pushes a new route if there isn't yet one on the stack.
diff --git a/versioned_docs/version-5.x/navigation-actions.md b/versioned_docs/version-5.x/navigation-actions.md
index bfe3034e294..23bb846dc45 100755
--- a/versioned_docs/version-5.x/navigation-actions.md
+++ b/versioned_docs/version-5.x/navigation-actions.md
@@ -80,9 +80,9 @@ If you want to preserve the existing screens but only want to modify the state,
```js
import { CommonActions } from '@react-navigation/native';
-navigation.dispatch(state => {
+navigation.dispatch((state) => {
// Remove the home route from the stack
- const routes = state.routes.filter(r => r.name !== 'Home');
+ const routes = state.routes.filter((r) => r.name !== 'Home');
return CommonActions.reset({
...state,
diff --git a/versioned_docs/version-5.x/navigation-container.md b/versioned_docs/version-5.x/navigation-container.md
index d58bef49356..885477f1d12 100644
--- a/versioned_docs/version-5.x/navigation-container.md
+++ b/versioned_docs/version-5.x/navigation-container.md
@@ -199,7 +199,7 @@ import { NavigationContainer } from '@react-navigation/native';
function App() {
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Home: 'feed/:sort',
@@ -230,7 +230,7 @@ Example:
```js
{
+const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default action
e.preventDefault();
});
@@ -89,7 +89,7 @@ Example:
name="Chat"
component={Chat}
listeners={{
- tabPress: e => {
+ tabPress: (e) => {
// Prevent default action
e.preventDefault();
},
@@ -106,7 +106,7 @@ Example:
name="Chat"
component={Chat}
listeners={({ navigation, route }) => ({
- tabPress: e => {
+ tabPress: (e) => {
// Prevent default action
e.preventDefault();
diff --git a/versioned_docs/version-5.x/navigation-prop.md b/versioned_docs/version-5.x/navigation-prop.md
index b2f8cb7cb65..2aef41e3b16 100755
--- a/versioned_docs/version-5.x/navigation-prop.md
+++ b/versioned_docs/version-5.x/navigation-prop.md
@@ -7,14 +7,18 @@ sidebar_label: Navigation prop
Each `screen` component in your app is provided with the `navigation` prop automatically. The prop contains various convenience functions that dispatch navigation actions. It looks like this:
- `navigation`
- - `navigate` - go to another screen, figures out the action it needs to take to do it
- - `reset` - wipe the navigator state and replace it with a new route
- - `goBack` - close active screen and move back in the stack
- - `setParams` - make changes to route's params
+ - `navigate` - go to the given screen, this will behave differently based on the navigator
+ - `goBack` - go back to the previous screen, this will pop the current screen when used in a stack
+ - `reset` - replace the navigation state of the navigator with the given state
+ - `setParams` - merge new params onto the route's params
- `dispatch` - send an action object to update the [navigation state](navigation-state.md)
- `setOptions` - update the screen's options
- `isFocused` - check whether the screen is focused
- - `addListener` - subscribe to updates to events from the navigators
+ - `canGoBack` - check whether it's possible to go back from the current screen
+ - `getState` - get the navigation state of the navigator
+ - `getParent` - get the navigation object of the parent screen, if any
+ - `addListener` - subscribe to events for the screen
+ - `removeListener` - unsubscribe from events for the screen
It's important to highlight the `navigation` prop is _not_ passed in to _all_ components; only `screen` components receive this prop automatically! React Navigation doesn't do any magic here. For example, if you were to define a `MyBackButton` component and render it as a child of a screen component, you would not be able to access the `navigation` prop on it. If, however, you wish to access the `navigation` prop in any of your components, you may use the [`useNavigation`](use-navigation.md) hook.
@@ -87,7 +91,11 @@ By default, the screen is identified by its name. But you can also customize it
For example, say you have specified a `getId` prop for `Profile` screen:
```js
- params.userId} />
+ params.userId}
+/>
```
Now, if you have a stack with the history `Home > Profile (userId: bob) > Settings` and you call `navigate(Profile, { userId: 'alice' })`, the resulting screens will be `Home > Profile (userId: bob) > Settings > Profile (userId: alice)` since it'll add a new `Profile` screen as no matching screen was found.
diff --git a/versioned_docs/version-5.x/navigation-state.md b/versioned_docs/version-5.x/navigation-state.md
index b3874b71503..ffa3dd8d3a3 100644
--- a/versioned_docs/version-5.x/navigation-state.md
+++ b/versioned_docs/version-5.x/navigation-state.md
@@ -4,7 +4,7 @@ title: Navigation state reference
sidebar_label: Navigation state
---
-The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as [resetting the state](navigation-actions.md#reset), [providing a custom initial state](navigation-container.md#initial-state) etc.
+The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as [resetting the state](navigation-actions.md#reset), [providing a custom initial state](navigation-container.md#initialstate) etc.
It's a JavaScript object which looks like this:
@@ -78,16 +78,13 @@ This also applies to the `index` property: `index` should be the last route in a
```js
navigation.reset({
index: 0,
- routes: [
- { name: 'Home' },
- { name: 'Profile' }
- ],
+ routes: [{ name: 'Home' }, { name: 'Profile' }],
});
```
React Navigation would correct `index` to 1, and display the route and perform navigation as intended.
-This feature comes handy when doing operations such as [reset](navigation-actions.md#reset), [providing a initial state](navigation-container.md#initial-state) etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a `routes` array without any keys and React Navigation will automatically add everything that's needed to make it work:
+This feature comes handy when doing operations such as [reset](navigation-actions.md#reset), [providing a initial state](navigation-container.md#initialstate) etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a `routes` array without any keys and React Navigation will automatically add everything that's needed to make it work:
```js
const state = {
@@ -117,4 +114,4 @@ It's also possible to provide invalid data such as non-existent screens and it'l
> If you want React Navigation to fix invalid state, you need to make sure that you don't have `stale: false` in the state object. State objects with `stale: false` are assumed to be valid state objects and React Navigation won't attempt to fix them.
-When you're providing a state object in [`initialState`](navigation-container.md#initial-state), React Navigation will always assume that it's a stale state object, which makes sure that things like state persistence work smoothly without extra manipulation of the state object.
+When you're providing a state object in [`initialState`](navigation-container.md#initialstate), React Navigation will always assume that it's a stale state object, which makes sure that things like state persistence work smoothly without extra manipulation of the state object.
diff --git a/versioned_docs/version-5.x/redux-integration.md b/versioned_docs/version-5.x/redux-integration.md
index c642bac2d97..7b825c0cee2 100755
--- a/versioned_docs/version-5.x/redux-integration.md
+++ b/versioned_docs/version-5.x/redux-integration.md
@@ -14,9 +14,7 @@ import { NavigationContainer } from '@react-navigation/native';
export default function App() {
return (
-
- {/* Screen configuration */}
-
+ {/* Screen configuration */}
);
}
@@ -35,7 +33,7 @@ function Counter({ value }) {
return Count: {value} ;
}
-const CounterContainer = connect(state => ({ value: state.count }))(Counter);
+const CounterContainer = connect((state) => ({ value: state.count }))(Counter);
```
```js
diff --git a/versioned_docs/version-5.x/stack-navigator.md b/versioned_docs/version-5.x/stack-navigator.md
index 692ea18f125..42c84ef7c6f 100755
--- a/versioned_docs/version-5.x/stack-navigator.md
+++ b/versioned_docs/version-5.x/stack-navigator.md
@@ -8,11 +8,9 @@ Provides a way for your app to transition between screens where each new screen
By default the stack navigator is configured to have the familiar iOS and Android look & feel: new screens slide in from the right on iOS, fade in from the bottom on Android. On iOS the stack navigator can also be configured to a modal style where screens slide in from the bottom.
-
-
-
-
-
+
+
+
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/stack):
@@ -72,8 +70,8 @@ Defines the style for rendering and transitions:
Specifies how the header should be rendered:
-- `float` - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
-- `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
+- `float` - The header is rendered above the screen and animates independently of the screen. This is default on iOS for non-modals.
+- `screen` - The header is rendered as part of the screen and animates together with the screen. This is default on other platforms.
- `none` - No header will be shown. It's recommended to use [`headerShown`](#headershown) option instead for more granularity.
#### `detachInactiveScreens`
@@ -115,8 +113,8 @@ header: ({ scene, previous, navigation }) => {
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
- ? options.title
- : scene.route.name;
+ ? options.title
+ : scene.route.name;
return (
r.key === route.key) > 0
+ navigation.getState().routes.findIndex((r) => r.key === route.key) > 0
? 0
: undefined,
...TransitionPresets.ModalPresentationIOS,
diff --git a/versioned_docs/version-5.x/state-persistence.md b/versioned_docs/version-5.x/state-persistence.md
index c48970b9ece..62dda684cd9 100755
--- a/versioned_docs/version-5.x/state-persistence.md
+++ b/versioned_docs/version-5.x/state-persistence.md
@@ -39,7 +39,9 @@ export default function App() {
if (Platform.OS !== 'web' && initialUrl == null) {
// Only restore state if there's no deep link and we're not on web
const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
- const state = savedStateString ? JSON.parse(savedStateString) : undefined;
+ const state = savedStateString
+ ? JSON.parse(savedStateString)
+ : undefined;
if (state !== undefined) {
setInitialState(state);
diff --git a/versioned_docs/version-5.x/testing.md b/versioned_docs/version-5.x/testing.md
index d5b3eb0d616..b0d516de974 100644
--- a/versioned_docs/version-5.x/testing.md
+++ b/versioned_docs/version-5.x/testing.md
@@ -33,7 +33,6 @@ jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
// As of react-native@0.64.X file has moved
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
-
```
Then we need to use this setup file in our jest config. You can add it under `setupFiles` option in a `jest.config.js` file or the `jest` key in `package.json`:
@@ -41,9 +40,7 @@ Then we need to use this setup file in our jest config. You can add it under `se
```json
{
"preset": "react-native",
- "setupFiles": [
- "/jest/setup.js"
- ],
+ "setupFiles": ["/jest/setup.js"]
}
```
diff --git a/versioned_docs/version-5.x/upgrading-from-4.x.md b/versioned_docs/version-5.x/upgrading-from-4.x.md
index 5824ac0e98a..d44e41d1ae3 100755
--- a/versioned_docs/version-5.x/upgrading-from-4.x.md
+++ b/versioned_docs/version-5.x/upgrading-from-4.x.md
@@ -8,18 +8,10 @@ sidebar_label: Upgrading from 4.x
React Navigation 5 has a completely new component based API. While the main concepts are the same, the API is different. In this guide, we aim to document all the differences so that it's easier to upgrade your app.
-If you have not installed React Navigation 5 yet, you can do so following the [Getting Started guide](getting-started.md).
+If you have not installed React Navigation 5 yet, you can do so by following the [Getting](getting-started.md) Started guide](getting-started.md).
To reuse code using the old API with minimal changes, you can use the [compatibility layer](compatibility.md).
-## Before you upgrade
-
-React Navigation 4 is still maintained and will stay compatible with the latest version of React Native. We'll accept small pull requests and release bug fixes. While we won't be actively working on new features for React Navigation 4, they may be occasionally backported.
-
-If React Navigation 4 is working well for you and you don't need any of the new capabilities of the new version, you can keep using it. You don't have to rewrite your navigation structure.
-
-However, if you're starting a new project, we recommend to use the latest version instead of React Navigation 4.
-
If you are upgrading from older versions of navigators, you should take a look at the guide for [upgrading to React Navigation 4](../version-4.x/upgrading-from-3.x.md) first, especially the part for [upgrading packages](../version-4.x/upgrading-from-3.x.md#upgrading-packages).
## Package names
@@ -156,7 +148,7 @@ Now we have added a [`useNavigationState`](use-navigation-state.md) which addres
function useIsFirstRouteInParent() {
const route = useRoute();
const isFirstRouteInParent = useNavigationState(
- state => state.routes[0].key === route.key
+ (state) => state.routes[0].key === route.key
);
return isFirstRouteInParent;
@@ -288,7 +280,7 @@ To achieve the previous use cases for these events where you added listeners wit
name="Chat"
component={Chat}
listeners={({ navigation, route }) => ({
- tabPress: e => {
+ tabPress: (e) => {
// Prevent default action
e.preventDefault();
diff --git a/versioned_docs/version-5.x/use-focus-effect.md b/versioned_docs/version-5.x/use-focus-effect.md
index 626d6f0eaf6..f609633a7eb 100755
--- a/versioned_docs/version-5.x/use-focus-effect.md
+++ b/versioned_docs/version-5.x/use-focus-effect.md
@@ -18,7 +18,7 @@ function Profile({ userId }) {
useFocusEffect(
React.useCallback(() => {
- const unsubscribe = API.subscribe(userId, user => setUser(user));
+ const unsubscribe = API.subscribe(userId, (user) => setUser(user));
return () => unsubscribe();
}, [userId])
@@ -43,17 +43,17 @@ When running asynchronous effects such as fetching data from server, it's import
```js
useFocusEffect(
React.useCallback(() => {
- const abortController = new AbortController()
+ const abortController = new AbortController();
const fetchUser = async () => {
try {
const user = await fetch(`https://example.com/users/${userId}`, {
- signal: abortController.signal
+ signal: abortController.signal,
});
setUser(user);
} catch (e) {
- if (e.name !== 'AbortError'){
+ if (e.name !== 'AbortError') {
// Handle error
}
}
@@ -62,7 +62,7 @@ useFocusEffect(
fetchUser();
return () => {
- abortController.abort()
+ abortController.abort();
};
}, [userId])
);
@@ -114,7 +114,7 @@ function FetchUserData({ userId, onUpdate }) {
// ...
class Profile extends React.Component {
- _handleUpdate = user => {
+ _handleUpdate = (user) => {
// Do something with user object
};
diff --git a/versioned_docs/version-5.x/use-is-focused.md b/versioned_docs/version-5.x/use-is-focused.md
index aeeaf0e233b..3258a360509 100755
--- a/versioned_docs/version-5.x/use-is-focused.md
+++ b/versioned_docs/version-5.x/use-is-focused.md
@@ -35,7 +35,7 @@ class Profile extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const isFocused = useIsFocused();
return ;
diff --git a/versioned_docs/version-5.x/use-linking.md b/versioned_docs/version-5.x/use-linking.md
index 053f0ba689b..c566e800982 100755
--- a/versioned_docs/version-5.x/use-linking.md
+++ b/versioned_docs/version-5.x/use-linking.md
@@ -14,17 +14,17 @@ Example:
```js
import * as React from 'react';
import { ScrollView } from 'react-native';
-import { useLinking , NavigationContainer } from '@react-navigation/native';
+import { useLinking, NavigationContainer } from '@react-navigation/native';
export default function App() {
const ref = React.useRef();
const { getInitialState } = useLinking(ref, {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Chat: 'feed/:sort',
- }
+ },
},
});
@@ -34,7 +34,7 @@ export default function App() {
React.useEffect(() => {
getInitialState()
.catch(() => {})
- .then(state => {
+ .then((state) => {
if (state !== undefined) {
setInitialState(state);
}
@@ -69,11 +69,11 @@ Example:
```js
useLinking(ref, {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Chat: 'feed/:sort',
- }
+ },
},
});
```
@@ -191,16 +191,16 @@ Example:
```js
useLinking(ref, {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Chat: 'feed/:sort',
- }
+ },
},
getStateFromPath(path, config) {
// Return a state object here
// You can also reuse the default logic by importing `getStateFromPath` from `@react-navigation/native`
- }
+ },
});
```
@@ -212,15 +212,15 @@ Example:
```js
useLinking(ref, {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Chat: 'feed/:sort',
- }
+ },
},
getPathFromState(state, config) {
// Return a path string here
// You can also reuse the default logic by importing `getPathFromState` from `@react-navigation/native`
- }
+ },
});
```
diff --git a/versioned_docs/version-5.x/use-navigation-state.md b/versioned_docs/version-5.x/use-navigation-state.md
index 8ed6fc30104..92e7652a2f4 100755
--- a/versioned_docs/version-5.x/use-navigation-state.md
+++ b/versioned_docs/version-5.x/use-navigation-state.md
@@ -11,13 +11,13 @@ sidebar_label: useNavigationState
It takes a selector function as an argument. The selector will receive the full [navigation state](navigation-state.md) and can return a specific value from the state:
```js
-const index = useNavigationState(state => state.index);
+const index = useNavigationState((state) => state.index);
```
The selector function helps to reduce unnecessary re-renders, so your screen will re-render only when that's something you care about. If you actually need the whole state object, you can do this explicitly:
```js
-const state = useNavigationState(state => state);
+const state = useNavigationState((state) => state);
```
> Note: This hook is useful for advanced cases and it's easy to introduce performance issues if you're not careful. For most of the cases, you don't need the navigator's state.
@@ -40,7 +40,7 @@ In this example, even if you push a new screen, this text won't update. If you u
```js
function Profile() {
- const routesLength = useNavigationState(state => state.routes.length);
+ const routesLength = useNavigationState((state) => state.routes.length);
return Number of routes: {routesLength} ;
}
@@ -61,8 +61,8 @@ class Profile extends React.Component {
}
// Wrap and export
-export default function(props) {
- const routesLength = useNavigationState(state => state.routes.length);
+export default function (props) {
+ const routesLength = useNavigationState((state) => state.routes.length);
return ;
}
diff --git a/versioned_docs/version-5.x/use-navigation.md b/versioned_docs/version-5.x/use-navigation.md
index e1c4e01425b..07b9ce9d895 100755
--- a/versioned_docs/version-5.x/use-navigation.md
+++ b/versioned_docs/version-5.x/use-navigation.md
@@ -46,7 +46,7 @@ class MyBackButton extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const navigation = useNavigation();
return ;
diff --git a/versioned_docs/version-5.x/use-route.md b/versioned_docs/version-5.x/use-route.md
index 1539f343bec..1de65f7115e 100755
--- a/versioned_docs/version-5.x/use-route.md
+++ b/versioned_docs/version-5.x/use-route.md
@@ -39,7 +39,7 @@ class MyText extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const route = useRoute();
return ;
diff --git a/versioned_docs/version-5.x/use-theme.md b/versioned_docs/version-5.x/use-theme.md
index 7807e031e70..13e70d0133d 100644
--- a/versioned_docs/version-5.x/use-theme.md
+++ b/versioned_docs/version-5.x/use-theme.md
@@ -40,7 +40,7 @@ class MyButton extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const theme = useTheme();
return ;
diff --git a/versioned_docs/version-6.x/auth-flow.md b/versioned_docs/version-6.x/auth-flow.md
index e597965b5a5..26b8fafea93 100755
--- a/versioned_docs/version-6.x/auth-flow.md
+++ b/versioned_docs/version-6.x/auth-flow.md
@@ -323,7 +323,11 @@ So our updated code will look like following:
>
)}
-
+
>
```
diff --git a/versioned_docs/version-6.x/bottom-tab-navigator.md b/versioned_docs/version-6.x/bottom-tab-navigator.md
index 3124e7da35e..c33c91fabbc 100755
--- a/versioned_docs/version-6.x/bottom-tab-navigator.md
+++ b/versioned_docs/version-6.x/bottom-tab-navigator.md
@@ -6,18 +6,16 @@ sidebar_label: Bottom Tabs
A simple tab bar on the bottom of the screen that lets you switch between different routes. Routes are lazily initialized -- their screen components are not mounted until they are first focused.
-
-
-
-
-
+
+
+
## Installation
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/bottom-tabs):
```bash npm2yarn
-npm install @react-navigation/bottom-tabs
+npm install @react-navigation/bottom-tabs@^6.x
```
## API Definition
@@ -275,7 +273,7 @@ To show your screen under the tab bar, you can set the `position` style to absol
You also might need to add a bottom margin to your content if you have a absolutely positioned tab bar. React Navigation won't do it automatically.
-To get the height of the bottom tab bar, you can use `BottomTabBarHeightContext` with [React's Context API](https://reactjs.org/docs/context.html#contextconsumer) or `useBottomTabBarHeight`:
+To get the height of the bottom tab bar, you can use `BottomTabBarHeightContext` with [React's Context API](https://react.dev/reference/react/useContext) or `useBottomTabBarHeight`:
```js
import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
diff --git a/versioned_docs/version-6.x/configuring-links.md b/versioned_docs/version-6.x/configuring-links.md
index 43553d80e67..cd9ebd50e60 100644
--- a/versioned_docs/version-6.x/configuring-links.md
+++ b/versioned_docs/version-6.x/configuring-links.md
@@ -47,13 +47,13 @@ You can also pass a [`fallback`](navigation-container.md#fallback) prop to `Navi
## Prefixes
-The `prefixes` option can be used to specify custom schemes (e.g. `mychat://`) as well as host & domain names (e.g. `https://mychat.com`) if you have configured [Universal Links](https://developer.apple.com/ios/universal-links/) or [Android App Links](https://developer.android.com/training/app-links).
+The `prefixes` option can be used to specify custom schemes (e.g. `example://`) as well as host & domain names (e.g. `https://example.com`) if you have configured [Universal Links](https://developer.apple.com/ios/universal-links/) or [Android App Links](https://developer.android.com/training/app-links).
For example:
```js
const linking = {
- prefixes: ['mychat://', 'https://mychat.com'],
+ prefixes: ['example://', 'https://example.com'],
};
```
@@ -61,14 +61,29 @@ Note that the `prefixes` option is not supported on Web. The host & domain names
### Multiple subdomains
-To match all subdomains of an associated domain, you can specify a wildcard by prefixing `*`. before the beginning of a specific domain. Note that an entry for `*.mychat.com` does not match `mychat.com` because of the period after the asterisk. To enable matching for both `*.mychat.com` and `mychat.com`, you need to provide a separate prefix entry for each.
+To match all subdomains of an associated domain, you can specify a wildcard by prefixing `*`. before the beginning of a specific domain. Note that an entry for `*.example.com` does not match `example.com` because of the period after the asterisk. To enable matching for both `*.example.com` and `example.com`, you need to provide a separate prefix entry for each.
```js
const linking = {
- prefixes: ['mychat://', 'https://mychat.com', 'https://*.mychat.com'],
+ prefixes: ['example://', 'https://example.com', 'https://*.example.com'],
};
```
+### Filtering certain paths
+
+Sometimes we may not want to handle all incoming links. For example, we may want to filter out links meant for authentication (e.g. `expo-auth-session`) or other purposes instead of navigating to a specific screen.
+
+To achieve this, you can use the `filter` option:
+
+```js
+const linking = {
+ prefixes: ['example://', 'https://example.com'],
+ filter: (url) => !url.includes('+expo-auth-session'),
+};
+```
+
+This is not supported on Web as we always need to handle the URL of the page.
+
## Mapping path to route names
To handle a link, you need to translate it to a valid [navigation state](navigation-state.md) and vice versa. For example, the path `/rooms/chat?user=jane` may be translated to a state object like this:
@@ -134,7 +149,7 @@ const config = {
};
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config,
};
@@ -494,7 +509,7 @@ Another thing to keep in mind is that it's not possible to pass params to the in
In this case, any params in the URL are only passed to the `Profile` screen which matches the path pattern `users/:id`, and the `Feed` screen doesn't receive any params. If you want to have the same params in the `Feed` screen, you can specify a [custom `getStateFromPath` function](navigation-container.md#linkinggetstatefrompath) and copy those params.
-Similarly, if you want to access params of a parent screen from a child screen, you can use [React Context](https://reactjs.org/docs/context.html) to expose them.
+Similarly, if you want to access params of a parent screen from a child screen, you can use [React Context](https://react.dev/reference/react/useContext) to expose them.
## Matching exact paths
@@ -664,7 +679,7 @@ Example:
```js
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Chat: 'feed/:sort',
diff --git a/versioned_docs/version-6.x/contributing.md b/versioned_docs/version-6.x/contributing.md
index aa31a3cb0b6..461dde2dcc7 100755
--- a/versioned_docs/version-6.x/contributing.md
+++ b/versioned_docs/version-6.x/contributing.md
@@ -15,23 +15,9 @@ Here are some of the ways to contribute to the project:
- [Bug Fixes](#bug-fixes)
- [Suggesting a Feature](#suggesting-a-feature)
- [Big Pull Requests](#big-pull-requests)
-- [Information](#information)
- - [Issue Template](#issue-template)
- - [Pull Request Template](#pull-request-template)
- - [Forking the Repository](#forking-the-repository)
- - [Code Review Guidelines](#code-review-guidelines)
- - [Run the Example App](#run-the-example-app)
- - [Run Tests](#run-tests)
And here are a few helpful resources to aid in getting started:
-- [Contributing](#contributing)
- - [Reporting Bugs](#reporting-bugs)
- - [Improving the Documentation](#improving-the-documentation)
- - [Responding to Issues](#responding-to-issues)
- - [Bug Fixes](#bug-fixes)
- - [Suggesting a Feature](#suggesting-a-feature)
- - [Big Pull Requests](#big-pull-requests)
- [Information](#information)
- [Issue Template](#issue-template)
- [Pull Request Template](#pull-request-template)
@@ -47,7 +33,7 @@ And here are a few helpful resources to aid in getting started:
You can't write code without writing the occasional bug. Especially as React Navigation is moving quickly, bugs happen. When you think you've found one here's what to do:
1. Search the existing issues for one like what you're seeing. If you see one, add a 👍 reaction (please no +1 comments). Read through the comments and see if you can provide any more valuable information to the thread
-2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE.md).
+2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/6.x/.github/ISSUE_TEMPLATE/bug-report.yml).
Creating a high quality reproduction is critical. Without it we likely can't fix the bug and, in an ideal situation, you'll find out that it's not actually a bug of the library but simply done incorrectly in your project. Instant bug fix!
@@ -96,7 +82,7 @@ The reason we want to do this is to save everyone time. Maybe that feature alrea
### Issue Template
-Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE.md) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
+Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/6.x/.github/ISSUE_TEMPLATE/bug-report.yml) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
Yes, it takes time and effort to complete the issue template. But that's the only way to ask high quality questions that actually get responses.
@@ -104,7 +90,7 @@ Would you rather take 1 minute to create an incomplete issue report and wait mon
### Pull Request Template
-Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/main/.github/PULL_REQUEST.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
+Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/6.x/.github/PULL_REQUEST_TEMPLATE.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
### Forking the Repository
diff --git a/versioned_docs/version-6.x/custom-android-back-button-handling.md b/versioned_docs/version-6.x/custom-android-back-button-handling.md
index 78cafc54bf5..963d79eb8d0 100755
--- a/versioned_docs/version-6.x/custom-android-back-button-handling.md
+++ b/versioned_docs/version-6.x/custom-android-back-button-handling.md
@@ -27,7 +27,10 @@ function ScreenWithCustomBackBehavior() {
}
};
- const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress);
+ const subscription = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ onBackPress
+ );
return () => subscription.remove();
}, [isSelectionModeEnabled, disableSelectionMode])
diff --git a/versioned_docs/version-6.x/custom-navigators.md b/versioned_docs/version-6.x/custom-navigators.md
index b2939bce632..372227a81c8 100755
--- a/versioned_docs/version-6.x/custom-navigators.md
+++ b/versioned_docs/version-6.x/custom-navigators.md
@@ -94,7 +94,7 @@ function TabNavigator({
}}
style={{ flex: 1 }}
>
- {descriptors[route.key].options.title ?? route.name}
+ {descriptors[route.key].options.title ?? route.name}
))}
diff --git a/versioned_docs/version-6.x/custom-routers.md b/versioned_docs/version-6.x/custom-routers.md
index 7ee96cfb149..8dc1d1b8cc1 100755
--- a/versioned_docs/version-6.x/custom-routers.md
+++ b/versioned_docs/version-6.x/custom-routers.md
@@ -155,7 +155,7 @@ Let's say you want to add a custom action to clear the history:
```js
import { TabRouter } from '@react-navigation/native';
-const MyTabRouter = options => {
+const MyTabRouter = (options) => {
const router = TabRouter(options);
return {
@@ -191,7 +191,7 @@ Sometimes you may want to prevent some navigation activity, depending on your ro
```js
import { StackRouter } from '@react-navigation/native';
-const MyStackRouter = options => {
+const MyStackRouter = (options) => {
const router = StackRouter(options);
return {
diff --git a/versioned_docs/version-6.x/deep-linking.md b/versioned_docs/version-6.x/deep-linking.md
index 29e8c1b75c5..e112f3f7f81 100755
--- a/versioned_docs/version-6.x/deep-linking.md
+++ b/versioned_docs/version-6.x/deep-linking.md
@@ -17,12 +17,12 @@ Below, we'll go through required configurations so that the deep link integratio
## Setup with Expo projects
-First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `mychat` then a link to your app would be `mychat://`. You can register for a scheme in your `app.json` by adding a string under the scheme key:
+First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `example` then a link to your app would be `example://`. You can register for a scheme in your `app.json` by adding a string under the scheme key:
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -69,7 +69,7 @@ const linking = {
### Setup on iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
You'll need to link `RCTLinking` to your project by following the steps described here. To be able to listen to incoming app links, you'll need to add the following lines to `AppDelegate.m` in your project:
@@ -104,12 +104,12 @@ Now you need to add the scheme to your project configuration.
The easiest way to do this is with the `uri-scheme` package by running the following:
```bash
-npx uri-scheme add mychat --ios
+npx uri-scheme add example --ios
```
If you want to do it manually, open the project (e.g. `SimpleApp/ios/SimpleApp.xcworkspace`) in Xcode. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
To make sure Universal Links work in your app, you also need to setup [Associated Domains](https://developer.apple.com/documentation/Xcode/supporting-associated-domains) on your server.
@@ -129,7 +129,7 @@ If you're using React Navigation within a hybrid app - an iOS app that has both
To configure the external linking in Android, you can create a new intent in the manifest.
-The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add mychat --android`.
+The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add example --android`.
If you want to add it manually, open up `SimpleApp/android/app/src/main/AndroidManifest.xml`, and make the following adjustments:
@@ -148,12 +148,12 @@ If you want to add it manually, open up `SimpleApp/android/app/src/main/AndroidM
-
+
```
-Similar to Universal Links on iOS, you can also use a domain to associate the app with your website on Android by [verifying Android App Links](https://developer.android.com/training/app-links/verify-site-associations). First, you need to configure your `AndroidManifest.xml`:
+Similar to Universal Links on iOS, you can also use a domain to associate the app with your website on Android by [verifying Android App Links](https://developer.android.com/training/app-links/verify-android-applinks). First, you need to configure your `AndroidManifest.xml`:
1. Add `android:autoVerify="true"` to your `` entry.
2. Add your domain's `scheme` and `host` in a new `` entry inside the ``.
@@ -172,7 +172,7 @@ After adding them, it should look like this:
-
+
@@ -185,7 +185,7 @@ After adding them, it should look like this:
```
-Then, you need to [declare the association](https://developer.android.com/training/app-links/verify-site-associations#web-assoc) between your website and your intent filters by hosting a Digital Asset Links JSON file.
+Then, you need to [declare the association](https://developer.android.com/training/app-links/verify-android-applinks#web-assoc) between your website and your intent filters by hosting a Digital Asset Links JSON file.
## Testing deep links
@@ -218,7 +218,7 @@ npx uri-scheme open [your deep link] --[ios|android]
For example:
```bash
-npx uri-scheme open "mychat://chat/jane" --ios
+npx uri-scheme open "example://chat/jane" --ios
```
Or if using Expo client:
@@ -238,7 +238,7 @@ xcrun simctl openurl booted [your deep link]
For example:
```bash
-xcrun simctl openurl booted "mychat://chat/jane"
+xcrun simctl openurl booted "example://chat/jane"
```
### Testing with `adb` on Android
@@ -252,7 +252,7 @@ adb shell am start -W -a android.intent.action.VIEW -d [your deep link] [your an
For example:
```bash
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/jane" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/jane" com.simpleapp
```
Or if using Expo client:
diff --git a/versioned_docs/version-6.x/devtools.md b/versioned_docs/version-6.x/devtools.md
index 6b74c725315..eac28d62c24 100644
--- a/versioned_docs/version-6.x/devtools.md
+++ b/versioned_docs/version-6.x/devtools.md
@@ -9,7 +9,7 @@ Developer tools to make debugging easier when using React Navigation.
To use the developer tools, install [`@react-navigation/devtools`](https://github.com/react-navigation/react-navigation/tree/master/packages/devtools):
```bash npm2yarn
-npm install @react-navigation/devtools
+npm install @react-navigation/devtools@^6.x
```
Hooks from this package only work during development and are disabled in production. You don't need to do anything special to remove them from the production build.
@@ -47,7 +47,10 @@ To use the hook, import it and pass a `ref` to the `NavigationContainer` as its
```js
import * as React from 'react';
-import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
import { useFlipper } from '@react-navigation/devtools';
export default function App() {
@@ -77,7 +80,10 @@ To use the hook, import it and pass a `ref` to the `NavigationContainer` as its
```js
import * as React from 'react';
-import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
import { useReduxDevToolsExtension } from '@react-navigation/devtools';
export default function App() {
diff --git a/versioned_docs/version-6.x/drawer-based-navigation.md b/versioned_docs/version-6.x/drawer-based-navigation.md
index 46b3c9b6994..5fc6692ae2c 100755
--- a/versioned_docs/version-6.x/drawer-based-navigation.md
+++ b/versioned_docs/version-6.x/drawer-based-navigation.md
@@ -6,12 +6,6 @@ sidebar_label: Drawer navigation
Common pattern in navigation is to use drawer from left (sometimes right) side for navigating between screens.
-
-
-
-
-
-
Before continuing, first install and configure [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer) and its dependencies following the [installation instructions](drawer-navigator.md#installation).
## Minimal example of drawer-based navigation
@@ -60,6 +54,10 @@ export default function App() {
}
```
+
+
+
+
## Opening and closing drawer
To open and close drawer, use the following helpers:
diff --git a/versioned_docs/version-6.x/drawer-layout.md b/versioned_docs/version-6.x/drawer-layout.md
index b332d86feda..916b2160e40 100644
--- a/versioned_docs/version-6.x/drawer-layout.md
+++ b/versioned_docs/version-6.x/drawer-layout.md
@@ -6,11 +6,9 @@ sidebar_label: Drawer Layout
A cross-platform Drawer component for React Native implemented using [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/).
-
-
-
-
-
+
+
+
This package doesn't integrate with React Navigation. If you want to integrate the drawer layout with React Navigation's navigation system, e.g. want to show screens in the drawer and be able to navigate between them using `navigation.navigate` etc, use [Drawer Navigator](drawer-navigator.md) instead.
@@ -40,12 +38,25 @@ Then, you need to install and configure the libraries that are required by the d
The Drawer supports both Reanimated 1 and the latest version of Reanimated. If you want to use the latest version of Reanimated, make sure to configure it following the [installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started).
-2. To finalize installation of `react-native-gesture-handler`, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+2. To finalize the installation of `react-native-gesture-handler`, we need to conditionally import it. To do this, create 2 files:
- ```js
+ ```js title="gesture-handler.native.js"
+ // Only import react-native-gesture-handler on native platforms
import 'react-native-gesture-handler';
```
+ ```js title="gesture-handler.js"
+ // Don't import react-native-gesture-handler on web
+ ```
+
+ Now, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+
+ ```js
+ import './gesture-handler';
+ ```
+
+ Since the drawer layout doesn't use `react-native-gesture-handler` on Web, this avoids unnecessarily increasing the bundle size.
+
:::warning
If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
@@ -54,9 +65,9 @@ Then, you need to install and configure the libraries that are required by the d
3. If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
-```bash
-npx pod-install ios
-```
+ ```bash
+ npx pod-install ios
+ ```
We're done! Now you can build and run the app on your device/simulator.
diff --git a/versioned_docs/version-6.x/drawer-navigator.md b/versioned_docs/version-6.x/drawer-navigator.md
index d0087e2a794..ce345ed0996 100644
--- a/versioned_docs/version-6.x/drawer-navigator.md
+++ b/versioned_docs/version-6.x/drawer-navigator.md
@@ -6,11 +6,9 @@ sidebar_label: Drawer
Drawer Navigator renders a navigation drawer on the side of the screen which can be opened and closed via gestures.
-
-
-
-
-
+
+
+
This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use the drawer without React Navigation integration, use the library directly instead.
@@ -19,7 +17,7 @@ This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer):
```bash npm2yarn
-npm install @react-navigation/drawer
+npm install @react-navigation/drawer@^6.x
```
Then, you need to install and configure the libraries that are required by the drawer navigator:
@@ -40,12 +38,25 @@ Then, you need to install and configure the libraries that are required by the d
The Drawer supports both Reanimated 1 and the latest version of Reanimated. If you want to use the latest version of Reanimated, make sure to configure it following the [installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started).
-2. To finalize installation of `react-native-gesture-handler`, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+2. To finalize the installation of `react-native-gesture-handler`, we need to conditionally import it. To do this, create 2 files:
- ```js
+ ```js title="gesture-handler.native.js"
+ // Only import react-native-gesture-handler on native platforms
import 'react-native-gesture-handler';
```
+ ```js title="gesture-handler.js"
+ // Don't import react-native-gesture-handler on web
+ ```
+
+ Now, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+
+ ```js
+ import './gesture-handler';
+ ```
+
+ Since the drawer navigator doesn't use `react-native-gesture-handler` on Web, this avoids unnecessarily increasing the bundle size.
+
:::warning
If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
@@ -54,9 +65,9 @@ Then, you need to install and configure the libraries that are required by the d
3. If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
-```bash
-npx pod-install ios
-```
+ ```bash
+ npx pod-install ios
+ ```
## API Definition
diff --git a/versioned_docs/version-6.x/elements.md b/versioned_docs/version-6.x/elements.md
index c5ee5afa42d..6c836d3b41f 100644
--- a/versioned_docs/version-6.x/elements.md
+++ b/versioned_docs/version-6.x/elements.md
@@ -11,14 +11,54 @@ A component library containing the UI elements and helpers used in React Navigat
To use this package, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/elements`](https://github.com/react-navigation/react-navigation/tree/main/packages/elements):
```bash npm2yarn
-npm install @react-navigation/elements
+npm install @react-navigation/elements@^6.x
```
## Components
### `Header`
-A component that can be used as a header. It accepts the following props:
+A component that can be used as a header. This is used by all the navigators by default.
+
+Usage:
+
+```js
+import { Header } from '@react-navigation/elements';
+
+function MyHeader() {
+ return ;
+}
+```
+
+To use the header in a navigator, you can use the `header` option in the screen options:
+
+```js
+import { Header, getHeaderTitle } from '@react-navigation/elements';
+
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+ (
+
+ ),
+ }}
+ >
+
+
+ );
+}
+```
+
+:::note
+
+This doesn't replicate the behavior of the header in stack and native stack navigators as the stack navigator also includes animations, and the native stack navigator header is provided by the native platform.
+
+:::
+
+It accepts the following props:
#### `headerTitle`
@@ -124,7 +164,7 @@ This is useful if you want to render a semi-transparent header or a blurred back
Note that if you don't want your content to appear under the header, you need to manually add a top margin to your content. React Navigation won't do it automatically.
-To get the height of the header, you can use [`HeaderHeightContext`](#headerheightcontext) with [React's Context API](https://reactjs.org/docs/context.html#contextconsumer) or [`useHeaderHeight`](#useheaderheight).
+To get the height of the header, you can use [`HeaderHeightContext`](#headerheightcontext) with [React's Context API](https://react.dev/reference/react/useContext) or [`useHeaderHeight`](#useheaderheight).
#### `headerBackground`
diff --git a/versioned_docs/version-6.x/function-after-focusing-screen.md b/versioned_docs/version-6.x/function-after-focusing-screen.md
index c97f17a3ae7..e1a6ed08e14 100755
--- a/versioned_docs/version-6.x/function-after-focusing-screen.md
+++ b/versioned_docs/version-6.x/function-after-focusing-screen.md
@@ -47,7 +47,7 @@ In most cases, it's recommended to use the `useFocusEffect` hook instead of addi
## Triggering an action with the `useFocusEffect` hook
-React Navigation provides a [hook](https://reactjs.org/docs/hooks-intro.html) that runs an effect when the screen comes into focus and cleans it up when it goes out of focus. This is useful for cases such as adding event listeners, for fetching data with an API call when a screen becomes focused, or any other action that needs to happen once the screen comes into view.
+React Navigation provides a [hook](use-focus-effect.md) that runs an effect when the screen comes into focus and cleans it up when it goes out of focus. This is useful for cases such as adding event listeners, for fetching data with an API call when a screen becomes focused, or any other action that needs to happen once the screen comes into view.
This is particularly handy when we are trying to stop something when the page is unfocused, like stopping a video or audio file from playing, or stopping the tracking of a user's location.
@@ -61,7 +61,7 @@ function Profile({ userId }) {
useFocusEffect(
React.useCallback(() => {
- const unsubscribe = API.subscribe(userId, user => setUser(data));
+ const unsubscribe = API.subscribe(userId, (user) => setUser(data));
return () => unsubscribe();
}, [userId])
@@ -75,7 +75,7 @@ See the [`useFocusEffect`](https://reactnavigation.org/docs/use-focus-effect/) d
## Re-rendering screen with the `useIsFocused` hook
-React Navigation provides a [hook](https://reactjs.org/docs/hooks-intro.html) that returns a boolean indicating whether the screen is focused or not.
+React Navigation provides a [hook](use-is-focused.md) that returns a boolean indicating whether the screen is focused or not.
The hook will return `true` when the screen is focused and `false` when our component is no longer focused. This enables us to render something conditionally based on whether the user is on the screen or not.
diff --git a/versioned_docs/version-6.x/getting-started.md b/versioned_docs/version-6.x/getting-started.md
index ce33910b74d..c2ac1931f69 100755
--- a/versioned_docs/version-6.x/getting-started.md
+++ b/versioned_docs/version-6.x/getting-started.md
@@ -12,7 +12,7 @@ If you're already familiar with JavaScript, React and React Native, then you'll
Here are some resources to help you out:
-1. [React Native Express](https://www.reactnative.express) (Sections 1 to 4)
+1. [React Native](https://reactnative.dev/docs/getting-started)
2. [Main Concepts of React](https://react.dev/learn)
3. [React Hooks](https://react.dev/reference/react)
4. [React Context](https://react.dev/learn/passing-data-deeply-with-context) (Advanced)
@@ -20,7 +20,7 @@ Here are some resources to help you out:
## Minimum requirements
- `react-native` >= 0.63.0
-- `expo` >= 41 (if you use [Expo](https://expo.io))
+- `expo` >= 41 (if you use [Expo Go](https://expo.dev/go))
- `typescript` >= 4.1.0 (if you use [TypeScript](https://www.typescriptlang.org))
## Installation
@@ -28,7 +28,7 @@ Here are some resources to help you out:
Install the required packages in your React Native project:
```bash npm2yarn
-npm install @react-navigation/native
+npm install @react-navigation/native@^6.x
```
React Navigation is made up of some core utilities and those are then used by navigators to create the navigation structure in your app. Don't worry too much about this for now, it'll become clear soon enough! To frontload the installation work, let's also install and configure dependencies used by most navigators, then we can move forward with starting to write some code.
@@ -61,8 +61,6 @@ You might get warnings related to peer dependencies after installation. They are
:::
-From React Native 0.60 and higher, [linking is automatic](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md). So you **don't need to run** `react-native link`.
-
If you're on a Mac and developing for iOS, you need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
```bash
diff --git a/versioned_docs/version-6.x/group.md b/versioned_docs/version-6.x/group.md
index 10a702b8626..fda544f2930 100644
--- a/versioned_docs/version-6.x/group.md
+++ b/versioned_docs/version-6.x/group.md
@@ -4,7 +4,7 @@ title: Group
sidebar_label: Group
---
-`Group` components are used to group several [screens](screen.md) inside a navigator.
+`Group` components are used to group several [screens](screen.md) inside a navigator for organizational purposes. They can also be used to apply the same options such as header styles to a group of screens.
A `Group` is returned from a `createXNavigator` function:
diff --git a/versioned_docs/version-6.x/handling-safe-area.md b/versioned_docs/version-6.x/handling-safe-area.md
index 31c00f09099..e5c0384c8a4 100755
--- a/versioned_docs/version-6.x/handling-safe-area.md
+++ b/versioned_docs/version-6.x/handling-safe-area.md
@@ -71,11 +71,11 @@ export default function App() {
{() => (
null}
screenOptions={{ headerShown: false }}
>
-
+
)}
diff --git a/versioned_docs/version-6.x/header-buttons.md b/versioned_docs/version-6.x/header-buttons.md
index 833b94d429f..2bc044849a4 100755
--- a/versioned_docs/version-6.x/header-buttons.md
+++ b/versioned_docs/version-6.x/header-buttons.md
@@ -35,6 +35,8 @@ function StackScreen() {
}
```
+
+
When we define our button this way, the `this` variable in `options` is _not_ the `HomeScreen` instance, so you can't call `setState` or any instance methods on it. This is pretty important because it's extremely common to want the buttons in your header to interact with the screen that the header belongs to. So, we will look how to do this next.
> 💡 Please note that a community-developed library for rendering buttons in the header with the correct styling is available: [react-navigation-header-buttons](https://github.com/vonovak/react-navigation-header-buttons).
@@ -55,9 +57,7 @@ function StackScreen() {
options={({ navigation, route }) => ({
headerTitle: (props) => ,
// Add a placeholder button without the `onPress` to avoid flicker
- headerRight: () => (
-
- ),
+ headerRight: () => ,
})}
/>
@@ -81,6 +81,10 @@ function HomeScreen({ navigation }) {
}
```
+
+
+
+
Here we update the `headerRight` with a button with `onPress` handler that has access to the component's state and can update it.
## Customizing the back button
@@ -91,6 +95,22 @@ You can change the label behavior with `headerBackTitle` and style it with `head
To customize the back button image, you can use `headerBackImageSource` ([read more](native-stack-navigator.md#headerbackimagesource)).
+```js
+
+
+
+
+```
+
+
+
## Overriding the back button
The back button will be rendered automatically in a stack navigator whenever it is possible for the user to go back from their current screen — in other words, the back button will be rendered whenever there is more than one screen in the stack.
diff --git a/versioned_docs/version-6.x/headers.md b/versioned_docs/version-6.x/headers.md
index 24e5774211e..5cfd92bad79 100755
--- a/versioned_docs/version-6.x/headers.md
+++ b/versioned_docs/version-6.x/headers.md
@@ -26,6 +26,8 @@ function StackScreen() {
}
```
+
+
## Using params in the title
In order to use params in the title, we need to make `options` prop for the screen a function that returns a configuration object. It might be tempting to try to use `this.props` inside of `options`, but because it is defined before the component is rendered, `this` does not refer to an instance of the component and therefore no props are available. Instead, if we make `options` a function then React Navigation will call it with an object containing `{ navigation, route }` - in this case, all we care about is `route`, which is the same object that is passed to your screen props as `route` prop. You may recall that we can get the params through `route.params`, and so we do this below to extract a param and use it as a title.
@@ -173,6 +175,8 @@ function StackScreen() {
}
```
+
+
:::note
You might be wondering, why `headerTitle` when we provide a component and not `title`, like before? The reason is that `headerTitle` is a property that is specific to headers, whereas `title` will be used for tab bars, drawers etc. as well. The `headerTitle` defaults to a `Text` component that displays the `title`.
diff --git a/versioned_docs/version-6.x/hello-react-navigation.md b/versioned_docs/version-6.x/hello-react-navigation.md
index c6d3fa8d1ae..9a1ede73cd8 100755
--- a/versioned_docs/version-6.x/hello-react-navigation.md
+++ b/versioned_docs/version-6.x/hello-react-navigation.md
@@ -15,12 +15,12 @@ Let's start by demonstrating the most common navigator, `createNativeStackNaviga
The libraries we've installed so far are the building blocks and shared foundations for navigators, and each navigator in React Navigation lives in its own library. To use the native stack navigator, we need to install [`@react-navigation/native-stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack) :
```bash npm2yarn
-npm install @react-navigation/native-stack
+npm install @react-navigation/native-stack@^6.x
```
> 💡 `@react-navigation/native-stack` depends on `react-native-screens` and the other libraries that we installed in [Getting started](getting-started.md). If you haven't installed those yet, head over to that page and follow the installation instructions.
-### Creating a native stack navigator
+## Creating a native stack navigator
`createNativeStackNavigator` is a function that returns an object containing 2 properties: `Screen` and `Navigator`. Both of them are React components used for configuring the navigator. The `Navigator` should contain `Screen` elements as its children to define the configuration for routes.
@@ -69,7 +69,7 @@ The casing of the route name doesn't matter -- you can use lowercase `home` or c
:::
-### Configuring the navigator
+## Configuring the navigator
All of the route configuration is specified as props to our navigator. We haven't passed any props to our navigator, so it just uses the default configuration.
@@ -110,7 +110,7 @@ The `component` prop accepts component, not a render function. Don't pass an inl
:::
-### Specifying options
+## Specifying options
Each screen in the navigator can specify some options for the navigator, such as the title to render in the header. These options can be passed in the `options` prop for each screen component:
@@ -126,11 +126,11 @@ Each screen in the navigator can specify some options for the navigator, such as
Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can pass a `screenOptions` prop to the navigator.
-### Passing additional props
+## Passing additional props
Sometimes we might want to pass additional props to a screen. We can do that with 2 approaches:
-1. Use [React context](https://reactjs.org/docs/context.html) and wrap the navigator with a context provider to pass data to the screens (recommended).
+1. Use [React context](https://react.dev/reference/react/useContext) and wrap the navigator with a context provider to pass data to the screens (recommended).
2. Use a render callback for the screen instead of specifying a `component` prop:
```js
@@ -141,7 +141,7 @@ Sometimes we might want to pass additional props to a screen. We can do that wit
:::warning
-By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) or [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) for your screen components to avoid performance issues.
+By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://react.dev/reference/react/memo) or [`React.PureComponent`](https://react.dev/reference/react/PureComponent) for your screen components to avoid performance issues.
:::
diff --git a/versioned_docs/version-6.x/limitations.md b/versioned_docs/version-6.x/limitations.md
index 8ef876a59ff..0958770e95f 100755
--- a/versioned_docs/version-6.x/limitations.md
+++ b/versioned_docs/version-6.x/limitations.md
@@ -4,7 +4,7 @@ title: Limitations
sidebar_label: Limitations
---
-As a potential user of the library, it's important to know what you can and cannot do with it. Armed with this knowledge, you may choose to adopt a different library such as [`react-native=navigation`](https://github.com/wix/react-native-navigation) instead. We discuss the high level design decisions in the [pitch & anti-pitch](pitch.md) section, and here we will cover some of the use cases that are either not supported or are so difficult to do that they may as well be impossible. If any of the following limitations are dealbreakers for your app, React Navigation might not be for you.
+As a potential user of the library, it's important to know what you can and cannot do with it. Armed with this knowledge, you may choose to adopt a different library such as [`react-native-navigation`](https://github.com/wix/react-native-navigation) instead. We discuss the high level design decisions in the [pitch & anti-pitch](pitch.md) section, and here we will cover some of the use cases that are either not supported or are so difficult to do that they may as well be impossible. If any of the following limitations are dealbreakers for your app, React Navigation might not be for you.
## Limited right-to-left (RTL) layout support
diff --git a/versioned_docs/version-6.x/material-bottom-tab-navigator.md b/versioned_docs/version-6.x/material-bottom-tab-navigator.md
index 59f3dd39f64..77b23135028 100755
--- a/versioned_docs/version-6.x/material-bottom-tab-navigator.md
+++ b/versioned_docs/version-6.x/material-bottom-tab-navigator.md
@@ -21,7 +21,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)](getting-started.md), then install [`@react-navigation/material-bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/material-bottom-tabs):
```bash npm2yarn
-npm install @react-navigation/material-bottom-tabs react-native-paper react-native-vector-icons
+npm install @react-navigation/material-bottom-tabs@^6.x react-native-paper react-native-vector-icons
```
This API also requires that you install `react-native-vector-icons`! If you are using Expo managed workflow, it will work without any extra steps. Otherwise, [follow these installation instructions](https://github.com/oblador/react-native-vector-icons#installation).
diff --git a/versioned_docs/version-6.x/material-top-tab-navigator.md b/versioned_docs/version-6.x/material-top-tab-navigator.md
index de4cb9f5e13..1d1646e5889 100755
--- a/versioned_docs/version-6.x/material-top-tab-navigator.md
+++ b/versioned_docs/version-6.x/material-top-tab-navigator.md
@@ -6,11 +6,9 @@ sidebar_label: Material Top Tabs
A material-design themed tab bar on the top of the screen that lets you switch between different routes by tapping the tabs or swiping horizontally. Transitions are animated by default. Screen components for each route are mounted immediately.
-
-
-
-
-
+
+
+
This wraps [`react-native-tab-view`](tab-view.md). If you want to use the tab view without React Navigation integration, use the library directly instead.
@@ -19,7 +17,7 @@ This wraps [`react-native-tab-view`](tab-view.md). If you want to use the tab vi
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/material-top-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/material-top-tabs):
```bash npm2yarn
-npm install @react-navigation/material-top-tabs react-native-tab-view
+npm install @react-navigation/material-top-tabs@^6.x react-native-tab-view
```
Then, you need to install [`react-native-pager-view`](https://github.com/callstack/react-native-pager-view) which is required by the navigator.
@@ -310,8 +308,7 @@ Example:
screenOptions={{
tabBarGap: 10,
}}
->
-
+>
```
#### `tabBarAndroidRipple`
@@ -326,8 +323,7 @@ Example:
screenOptions={{
tabBarAndroidRipple: { borderless: false },
}}
->
-
+>
```
#### `tabBarPressColor`
diff --git a/versioned_docs/version-6.x/modal.md b/versioned_docs/version-6.x/modal.md
index be5ff7a74b1..40d3f25ad02 100755
--- a/versioned_docs/version-6.x/modal.md
+++ b/versioned_docs/version-6.x/modal.md
@@ -4,8 +4,6 @@ title: Opening a modal
sidebar_label: Opening a modal
---
-
-
A modal displays content that temporarily blocks interactions with the main view.
A modal is like a popup — it usually has a different transition animation, and is intended to focus on one particular interaction or piece of content.
@@ -61,6 +59,10 @@ function RootStackScreen() {
}
```
+
+
+
+
Here, we are creating 2 groups of screens using the `RootStack.Group` component. The first group is for our regular screens, and the second group is for our modal screens. For the modal group, we have specified `presentation: 'modal'` in `screenOptions`. This will apply this option to all the screens inside the group. This option will change the animation for the screens to animate from bottom-to-top rather than right to left. The `presentation` option for stack navigator can be either `card` (default) or `modal`. The `modal` behavior slides the screen in from the bottom and allows the user to swipe down from the top to dismiss it on iOS.
Instead of specifying this option for a group, it's also possible to specify it for a single screen using the `options` prop on `RootStack.Screen`.
diff --git a/versioned_docs/version-6.x/multiple-drawers.md b/versioned_docs/version-6.x/multiple-drawers.md
index 02ca5134f2b..59b0394e24e 100644
--- a/versioned_docs/version-6.x/multiple-drawers.md
+++ b/versioned_docs/version-6.x/multiple-drawers.md
@@ -190,6 +190,10 @@ export default function App() {
}
```
+
+
+
+
But there is one problem. When we call `navigation.openDrawer()` in our `HomeScreen`, it always opens the left drawer since it's the immediate parent of the screen.
To solve this, we need to use [`navigation.getParent`](navigation-prop.md#getparent) to refer to the right drawer which is the parent of the left drawer. So our code would look like:
diff --git a/versioned_docs/version-6.x/native-stack-navigator.md b/versioned_docs/version-6.x/native-stack-navigator.md
index 67f096165ae..4b286b0ac7c 100755
--- a/versioned_docs/version-6.x/native-stack-navigator.md
+++ b/versioned_docs/version-6.x/native-stack-navigator.md
@@ -15,7 +15,7 @@ One thing to keep in mind is that while `@react-navigation/native-stack` offers
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/native-stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack):
```bash npm2yarn
-npm install @react-navigation/native-stack
+npm install @react-navigation/native-stack@^6.x
```
## API Definition
@@ -166,7 +166,7 @@ This is useful if you want to render a semi-transparent header or a blurred back
Note that if you don't want your content to appear under the header, you need to manually add a top margin to your content. React Navigation won't do it automatically.
-To get the height of the header, you can use [`HeaderHeightContext`](elements.md#headerheightcontext) with [React's Context API](https://reactjs.org/docs/context.html#contextconsumer) or [`useHeaderHeight`](elements.md#useheaderheight).
+To get the height of the header, you can use [`HeaderHeightContext`](elements.md#headerheightcontext) with [React's Context API](https://react.dev/reference/react/useContext) or [`useHeaderHeight`](elements.md#useheaderheight).
#### `headerBlurEffect`
@@ -259,7 +259,17 @@ React.useLayoutEffect(() => {
}, [navigation]);
```
-Supported properties are described below.
+Supported properties are:
+
+##### `ref`
+
+Ref to manipulate the search input imperatively. It contains the following methods:
+
+- `focus` - focuses the search bar
+- `blur` - removes focus from the search bar
+- `setText` - sets the search bar's content to given value
+- `clearText` - removes any text present in the search bar input field
+- `cancelSearch` - cancel the search and close the search bar
##### `autoCapitalize`
@@ -447,15 +457,17 @@ Only supported on Android and iOS.
#### `statusBarStyle`
-Sets the status bar color (similar to the `StatusBar` component). Defaults to `auto`.
+Sets the status bar color (similar to the `StatusBar` component).
Supported values:
-- `"auto"`
+- `"auto"` (iOS only)
- `"inverted"` (iOS only)
- `"dark"`
- `"light"`
+Defaults to `auto` on iOS and `light` on Android.
+
Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
Only supported on Android and iOS.
diff --git a/versioned_docs/version-6.x/navigating-without-navigation-prop.md b/versioned_docs/version-6.x/navigating-without-navigation-prop.md
index 783c8529f78..2aceddd06a7 100755
--- a/versioned_docs/version-6.x/navigating-without-navigation-prop.md
+++ b/versioned_docs/version-6.x/navigating-without-navigation-prop.md
@@ -42,7 +42,7 @@ In the next step, we define `RootNavigation`, which is a simple module with func
import { createNavigationContainerRef } from '@react-navigation/native';
-export const navigationRef = createNavigationContainerRef()
+export const navigationRef = createNavigationContainerRef();
export function navigate(name, params) {
if (navigationRef.isReady()) {
@@ -104,7 +104,7 @@ To avoid this, you can use the `isReady()` method available on the ref as shown
import * as React from 'react';
-export const navigationRef = createNavigationContainerRef()
+export const navigationRef = createNavigationContainerRef();
export function navigate(name, params) {
if (navigationRef.isReady()) {
diff --git a/versioned_docs/version-6.x/navigating.md b/versioned_docs/version-6.x/navigating.md
index 2a4e3e1fd99..794fb5edb02 100755
--- a/versioned_docs/version-6.x/navigating.md
+++ b/versioned_docs/version-6.x/navigating.md
@@ -51,6 +51,10 @@ function HomeScreen({ navigation }) {
// ... other code from the previous section
```
+
+
+
+
Let's break this down:
- `navigation` - the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in the native stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
@@ -95,11 +99,9 @@ Let's suppose that we actually _want_ to add another details screen. This is pre
/>
```
-
-
-
-
-
+
+
+
Each time you call `push` we add a new route to the navigation stack. When you call `navigate` it first tries to find an existing route with that name, and only pushes a new route if there isn't yet one on the stack.
@@ -127,6 +129,10 @@ function DetailsScreen({ navigation }) {
}
```
+
+
+
+
:::note
On Android, React Navigation hooks in to the hardware back button and fires the `goBack()` function for you when the user presses it, so it behaves as the user would expect.
@@ -157,6 +163,10 @@ function DetailsScreen({ navigation }) {
}
```
+
+
+
+
## Summary
- `navigation.navigate('RouteName')` pushes a new route to the native stack navigator if it's not already in the stack, otherwise it jumps to that screen.
diff --git a/versioned_docs/version-6.x/navigation-actions.md b/versioned_docs/version-6.x/navigation-actions.md
index 84c3e6f1fdb..50e2878cbd0 100755
--- a/versioned_docs/version-6.x/navigation-actions.md
+++ b/versioned_docs/version-6.x/navigation-actions.md
@@ -80,9 +80,9 @@ If you want to preserve the existing screens but only want to modify the state,
```js
import { CommonActions } from '@react-navigation/native';
-navigation.dispatch(state => {
+navigation.dispatch((state) => {
// Remove all the screens after `Profile`
- const index = state.routes.findIndex(r => r.name === 'Profile');
+ const index = state.routes.findIndex((r) => r.name === 'Profile');
const routes = state.routes.slice(0, index + 1);
return CommonActions.reset({
diff --git a/versioned_docs/version-6.x/navigation-container.md b/versioned_docs/version-6.x/navigation-container.md
index 07ab452861b..5d48860e803 100644
--- a/versioned_docs/version-6.x/navigation-container.md
+++ b/versioned_docs/version-6.x/navigation-container.md
@@ -31,23 +31,24 @@ export default function App() {
## Ref
-It's also possible to attach a [`ref`](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) to the container to get access to various helper methods, for example, dispatch navigation actions. This should be used in rare cases when you don't have access to the `navigation` prop, such as a Redux middleware.
+It's also possible to attach a [`ref`](https://react.dev/learn/referencing-values-with-refs) to the container to get access to various helper methods, for example, dispatch navigation actions. This should be used in rare cases when you don't have access to the `navigation` prop, such as a Redux middleware.
Example:
```js
-import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
function App() {
const navigationRef = useNavigationContainerRef(); // You can also use a regular ref with `React.useRef()`
return (
- navigationRef.navigate('Home')}>
- Go home
-
+ navigationRef.navigate('Home')}>Go home
{/* ... */}
);
@@ -161,9 +162,7 @@ Prop that accepts initial state for the navigator. This can be useful for cases
Example:
```js
-
+
{/* ... */}
```
@@ -238,7 +237,7 @@ import { NavigationContainer } from '@react-navigation/native';
function App() {
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Home: 'feed/:sort',
@@ -269,7 +268,7 @@ Example:
```js
{/* content */}
-
+ ;
```
This option is not available on Web.
@@ -439,7 +438,7 @@ import messaging from '@react-native-firebase/messaging';
+
+
+
We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the tab bar to switch to the `SettingsScreen` and navigate to `ProfileScreen`. After this sequence of operations is done, all 4 of the screens are mounted! If you use the tab bar to switch back to the `HomeStack`, you'll notice you'll be presented with the `DetailsScreen` - the navigation state of the `HomeStack` has been preserved!
## React Navigation lifecycle events
@@ -104,6 +108,10 @@ function Profile() {
}
```
+
+
+
+
If you want to render different things based on if the screen is focused or not, you can use the [`useIsFocused`](use-is-focused.md) hook which returns a boolean indicating whether the screen is focused.
## Summary
diff --git a/versioned_docs/version-6.x/navigation-prop.md b/versioned_docs/version-6.x/navigation-prop.md
index 8afda205304..83fae07b54c 100755
--- a/versioned_docs/version-6.x/navigation-prop.md
+++ b/versioned_docs/version-6.x/navigation-prop.md
@@ -7,14 +7,18 @@ sidebar_label: Navigation prop
Each `screen` component in your app is provided with the `navigation` prop automatically. The prop contains various convenience functions that dispatch navigation actions. It looks like this:
- `navigation`
- - `navigate` - go to another screen, figures out the action it needs to take to do it
- - `reset` - wipe the navigator state and replace it with a new route
- - `goBack` - close active screen and move back in the stack
- - `setParams` - make changes to route's params
+ - `navigate` - go to the given screen, this will behave differently based on the navigator
+ - `goBack` - go back to the previous screen, this will pop the current screen when used in a stack
+ - `reset` - replace the navigation state of the navigator with the given state
+ - `setParams` - merge new params onto the route's params
- `dispatch` - send an action object to update the [navigation state](navigation-state.md)
- `setOptions` - update the screen's options
- `isFocused` - check whether the screen is focused
- - `addListener` - subscribe to updates to events from the navigators
+ - `canGoBack` - check whether it's possible to go back from the current screen
+ - `getState` - get the navigation state of the navigator
+ - `getParent` - get the navigation object of the parent screen, if any
+ - `addListener` - subscribe to events for the screen
+ - `removeListener` - unsubscribe from events for the screen
It's important to highlight the `navigation` prop is _not_ passed in to _all_ components; only `screen` components receive this prop automatically! React Navigation doesn't do any magic here. For example, if you were to define a `MyBackButton` component and render it as a child of a screen component, you would not be able to access the `navigation` prop on it. If, however, you wish to access the `navigation` prop in any of your components, you may use the [`useNavigation`](use-navigation.md) hook.
@@ -91,7 +95,11 @@ By default, the screen is identified by its name. But you can also customize it
For example, say you have specified a `getId` prop for `Profile` screen:
```js
- params.userId} />
+ params.userId}
+/>
```
Now, if you have a stack with the history `Home > Profile (userId: bob) > Settings` and you call `navigate(Profile, { userId: 'alice' })`, the resulting screens will be `Home > Profile (userId: bob) > Settings > Profile (userId: alice)` since it'll add a new `Profile` screen as no matching screen was found.
@@ -362,9 +370,7 @@ It accepts an optional ID parameter to refer to a specific parent navigator. For
To use an ID for a navigator, first pass a unique `id` prop:
```js
-
- {/* .. */}
-
+{/* .. */}
```
Then when using `getParent`, instead of:
diff --git a/versioned_docs/version-6.x/navigation-solutions-and-community-libraries.md b/versioned_docs/version-6.x/navigation-solutions-and-community-libraries.md
index 8a9c7d0afeb..5c0efe29270 100755
--- a/versioned_docs/version-6.x/navigation-solutions-and-community-libraries.md
+++ b/versioned_docs/version-6.x/navigation-solutions-and-community-libraries.md
@@ -57,3 +57,9 @@ Helps you to render buttons in the navigation bar and handle the styling so you
Provides simple HOCs that map react-navigation props to your screen components directly - ie. instead of `const user = this.props.route.params.activeUser`, you'd write `const user = this.props.activeUser`.
[github.com/vonovak/react-navigation-props-mapper](https://github.com/vonovak/react-navigation-props-mapper)
+
+## react-native-bottom-tabs
+
+This project aims to expose the native Bottom Tabs component to React Native. It also exposes SwiftUI's TabView on iOS and the material design tab bar on Android. Using `react-native-bottom-tabs` can bring several benefits, including multi-platform support and a native-feeling tab bar.
+
+[github.com/okwasniewski/react-native-bottom-tabs](https://github.com/okwasniewski/react-native-bottom-tabs)
diff --git a/versioned_docs/version-6.x/navigation-state.md b/versioned_docs/version-6.x/navigation-state.md
index 2ea0554b38c..46d2bf13a2c 100644
--- a/versioned_docs/version-6.x/navigation-state.md
+++ b/versioned_docs/version-6.x/navigation-state.md
@@ -4,7 +4,7 @@ title: Navigation state reference
sidebar_label: Navigation state
---
-The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as [resetting the state](navigation-actions.md#reset), [providing a custom initial state](navigation-container.md#initial-state) etc.
+The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as [resetting the state](navigation-actions.md#reset), [providing a custom initial state](navigation-container.md#initialstate) etc.
It's a JavaScript object which looks like this:
@@ -78,16 +78,13 @@ This also applies to the `index` property: `index` should be the last route in a
```js
navigation.reset({
index: 0,
- routes: [
- { name: 'Home' },
- { name: 'Profile' }
- ],
+ routes: [{ name: 'Home' }, { name: 'Profile' }],
});
```
React Navigation would correct `index` to 1, and display the route and perform navigation as intended.
-This feature comes handy when doing operations such as [reset](navigation-actions.md#reset), [providing a initial state](navigation-container.md#initial-state) etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a `routes` array without any keys and React Navigation will automatically add everything that's needed to make it work:
+This feature comes handy when doing operations such as [reset](navigation-actions.md#reset), [providing a initial state](navigation-container.md#initialstate) etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a `routes` array without any keys and React Navigation will automatically add everything that's needed to make it work:
```js
const state = {
@@ -121,4 +118,4 @@ If you want React Navigation to fix invalid state, you need to make sure that yo
:::
-When you're providing a state object in [`initialState`](navigation-container.md#initial-state), React Navigation will always assume that it's a stale state object, which makes sure that things like state persistence work smoothly without extra manipulation of the state object.
+When you're providing a state object in [`initialState`](navigation-container.md#initialstate), React Navigation will always assume that it's a stale state object, which makes sure that things like state persistence work smoothly without extra manipulation of the state object.
diff --git a/versioned_docs/version-6.x/nesting-navigators.md b/versioned_docs/version-6.x/nesting-navigators.md
index d5849d3eba7..64847d24d7b 100755
--- a/versioned_docs/version-6.x/nesting-navigators.md
+++ b/versioned_docs/version-6.x/nesting-navigators.md
@@ -64,7 +64,7 @@ If you want to achieve this behavior, see the guide for [screen options with nes
For example, any `params` passed to a screen in a nested navigator are in the `route` prop of that screen and aren't accessible from a screen in a parent or child navigator.
-If you need to access params of the parent screen from a child screen, you can use [React Context](https://reactjs.org/docs/context.html) to expose params to children.
+If you need to access params of the parent screen from a child screen, you can use [React Context](https://react.dev/reference/react/useContext) to expose params to children.
### Navigation actions are handled by current navigator and bubble up if couldn't be handled
@@ -123,7 +123,7 @@ function Root() {
-
+
);
}
@@ -193,6 +193,12 @@ navigation.navigate('Root', {
In the above case, you're navigating to the `Media` screen, which is in a navigator nested inside the `Sound` screen, which is in a navigator nested inside the `Settings` screen.
+:::warning
+
+The `screen` and related params are reserved for internal use and are managed by React Navigation. While you can access `route.params.screen` etc. in the parent screens, relying on them may lead to unexpected behavior.
+
+:::
+
### Rendering initial route defined in the navigator
By default, when you navigate a screen in the nested navigator, the specified screen is used as the initial screen and the initial route prop on the navigator is ignored. This behaviour is different from the React Navigation 4.
diff --git a/versioned_docs/version-6.x/next-steps.md b/versioned_docs/version-6.x/next-steps.md
index af25158836b..d20aacd5c30 100755
--- a/versioned_docs/version-6.x/next-steps.md
+++ b/versioned_docs/version-6.x/next-steps.md
@@ -4,10 +4,21 @@ title: Next steps
sidebar_label: Next steps
---
-You are now familiar with how to create a stack navigator, configure it on your screen components, navigate between routes, and display modals. Stack navigators and their related APIs will be the most frequently used tools in your React Navigation toolbelt, but there are problems that they don't solve. For example, you can't build tab-based navigation using a stack navigator — for that, you need to use a [TabNavigator](tab-based-navigation.md).
+You are now familiar with how to create a stack navigator, configure it on your screen components, navigate between routes, and display modals. Stack navigators and their related APIs will be the most frequently used tools in your React Navigation toolbelt, but there are problems that they don't solve. For example, you can't build tab-based navigation using a stack navigator — for that, you need to use a [Bottom Tabs Navigator](bottom-tab-navigator.md).
The rest of the documentation is organized around specific use cases, so you can jump between the sections under "Guides" as the need arises (but it also wouldn't hurt you to familiarize yourself with them pre-emptively!).
-While most users won't need to do this, if you are curious and want to learn more about how React Navigation works, it's recommended to work through the "Build your own Navigator" section.
+Some of the guides you may want to check out are:
+
+- [Tab navigation](tab-based-navigation.md): How to show tabs at the bottom of the screen.
+- [Drawer navigation](drawer-based-navigation.md): How to show a drawer from the left or right side of the screen.
+- [Authentication flows](auth-flow.md): How to handle authentication flows in your app.
+- [Supporting safe areas](handling-safe-area.md): How to handle safe areas such as statusbar in your app.
+- [Deep linking](deep-linking.md): How to handle deep linking and universal links in your app.
+- [Themes](themes.md): How to customize the look and feel of various UI elements.
+- [Testing with Jest](testing.md): How to test your navigation components.
+- [Configuring TypeScript](typescript.md): How to configure TypeScript for React Navigation.
+
+While most users won't need to do this, if you are curious and want to learn more about how React Navigation works, it's recommended to work through the [Navigation State reference](navigation-state.md) and [Build your own Navigator](custom-navigators.md) sections.
Good luck!
diff --git a/versioned_docs/version-6.x/params.md b/versioned_docs/version-6.x/params.md
index bb47fe19893..c6b796857b5 100755
--- a/versioned_docs/version-6.x/params.md
+++ b/versioned_docs/version-6.x/params.md
@@ -64,7 +64,9 @@ function DetailsScreen({ route, navigation }) {
}
```
-
+
+
+
## Initial params
@@ -156,6 +158,10 @@ function CreatePostScreen({ navigation, route }) {
}
```
+
+
+
+
Here, after you press "Done", the home screen's `route.params` will be updated to reflect the post text that you passed in `navigate`.
## Passing params to nested navigators
@@ -175,9 +181,9 @@ See [Nesting navigators](nesting-navigators.md) for more details on nesting.
## What should be in params
-It's important to understand what kind of data should be in params. Params are like options for a screen. They should only contain information to configure what's displayed in the screen. Avoid passing the full data which will be displayed on the screen itself (e.g. pass a user id instead of user object). Also avoid passing data which is used by multiple screens, such data should be in a global store.
+Params are essentially options for a screen. They should contain the minimal data required to show a screen, nothing more. If the data is used by multiple screens, it should be in a global store or global cache. Params is not designed for state management.
-You can also think of the route object like a URL. If your screen had a URL, what should be in the URL? Params shouldn't contain data that you think should not be in the URL. This often means that you should keep as little data as possible needed to determine what the screen is. Think of visiting a shopping website, when you are seeing product listings, the URL usually contains category name, type of sort, any filters etc., it doesn't contain the actual list of products displayed on the screen.
+You can think of the route object as a URL. If your screen had a URL, what should be in the URL? The same principles apply to params. Think of visiting a shopping website; when you see product listings, the URL usually contains category name, type of sort, any filters etc., not the actual list of products displayed on the screen.
For example, say if you have a `Profile` screen. When navigating to it, you might be tempted to pass the user object in the params:
@@ -193,15 +199,17 @@ navigation.navigate('Profile', {
});
```
-This looks convenient, and lets you access the user objects with `route.params.user` without any extra work.
+This looks convenient and lets you access the user objects with `route.params.user` without any extra work.
-However, this is an anti-pattern. Data such as user objects should be in your global store instead of the navigation state. Otherwise you have the same data duplicated in multiple places. This can lead to bugs such as the profile screen showing outdated data even if the user object has changed after navigation.
+However, this is an anti-pattern. There are many reasons why this is a bad idea:
-It also becomes problematic to link to the screen via deep linking or on the Web, since:
+- The same data is duplicated in multiple places. This can lead to bugs such as the profile screen showing outdated data even if the user object has changed after navigation.
+- Each screen that navigates to the `Profile` screen now needs to know how to fetch the user object - which increases the complexity of the code.
+- URLs to the screen (browser URL on the web, or deep links on native) will contain the user object. This is problematic:
-1. The URL is a representation of the screen, so it also needs to contain the params, i.e. full user object, which can make the URL very long and unreadable
-2. Since the user object is in the URL, it's possible to pass a random user object representing a user which doesn't exist, or has incorrect data in the profile
-3. If the user object isn't passed, or improperly formatted, this could result in crashes as the screen won't know how to handle it
+ 1. Since the user object is in the URL, it's possible to pass a random user object representing a user that doesn't exist or has incorrect data in the profile.
+ 2. If the user object isn't passed or improperly formatted, this could result in crashes as the screen won't know how to handle it.
+ 3. The URL can become very long and unreadable.
A better way is to pass only the ID of the user in params:
diff --git a/versioned_docs/version-6.x/preventing-going-back.md b/versioned_docs/version-6.x/preventing-going-back.md
index e777783bca0..dc230defe0a 100644
--- a/versioned_docs/version-6.x/preventing-going-back.md
+++ b/versioned_docs/version-6.x/preventing-going-back.md
@@ -57,6 +57,10 @@ function EditText({ navigation }) {
}
```
+
+
+
+
Previously, the way to do this was to:
- Override back button in header
diff --git a/versioned_docs/version-6.x/redux-integration.md b/versioned_docs/version-6.x/redux-integration.md
index 5f6b54d4a2b..015e6017591 100755
--- a/versioned_docs/version-6.x/redux-integration.md
+++ b/versioned_docs/version-6.x/redux-integration.md
@@ -14,9 +14,7 @@ import { NavigationContainer } from '@react-navigation/native';
export default function App() {
return (
-
- {/* Screen configuration */}
-
+ {/* Screen configuration */}
);
}
@@ -35,7 +33,7 @@ function Counter({ value }) {
return Count: {value} ;
}
-const CounterContainer = connect(state => ({ value: state.count }))(Counter);
+const CounterContainer = connect((state) => ({ value: state.count }))(Counter);
```
```js
diff --git a/versioned_docs/version-6.x/screen-options.md b/versioned_docs/version-6.x/screen-options.md
index 5fe11c40c4f..b9c8662ebfa 100644
--- a/versioned_docs/version-6.x/screen-options.md
+++ b/versioned_docs/version-6.x/screen-options.md
@@ -89,7 +89,7 @@ Similar to `options`, you can also pass a function to `screenOptions`. The funct
### `screenOptions` prop on the navigator
-You can pass a prop named `screenOptions` to the navigator component, where you can specify an object with different options. The options specified in `screenOptions` apply to all of the screens in the navigator. So this is a good place to add specify options that you want to configure for the whole navigator.
+You can pass a prop named `screenOptions` to the navigator component, where you can specify an object with different options. The options specified in `screenOptions` apply to all of the screens in the navigator. So this is a good place to specify options that you want to configure for the whole navigator.
Example:
diff --git a/versioned_docs/version-6.x/screen-tracking.md b/versioned_docs/version-6.x/screen-tracking.md
index 17edf38f7b6..d2649461288 100644
--- a/versioned_docs/version-6.x/screen-tracking.md
+++ b/versioned_docs/version-6.x/screen-tracking.md
@@ -43,7 +43,7 @@ export default () => {
if (previousRouteName !== currentRouteName) {
// Save the current route name for later comparison
routeNameRef.current = currentRouteName;
-
+
// Replace the line below to add the tracker from a mobile analytics SDK
await trackScreenView(currentRouteName);
}
diff --git a/versioned_docs/version-6.x/screen.md b/versioned_docs/version-6.x/screen.md
index a97eb9f7de7..5385e9d44ac 100644
--- a/versioned_docs/version-6.x/screen.md
+++ b/versioned_docs/version-6.x/screen.md
@@ -170,11 +170,11 @@ Render callback to return React Element to use for the screen:
```
-You can use this approach instead of the `component` prop if you need to pass additional props. Though we recommend using [React context](https://reactjs.org/docs/context.html) for passing data instead.
+You can use this approach instead of the `component` prop if you need to pass additional props. Though we recommend using [React context](https://react.dev/reference/react/useContext) for passing data instead.
:::warning
-By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) or [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) for your screen components to avoid performance issues.
+By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://react.dev/reference/react/memo) or [`React.PureComponent`](https://react.dev/reference/react/PureComponent) for your screen components to avoid performance issues.
:::
diff --git a/versioned_docs/version-6.x/shared-element-transitions.md b/versioned_docs/version-6.x/shared-element-transitions.md
index dd288f51f0e..9d545d71bac 100644
--- a/versioned_docs/version-6.x/shared-element-transitions.md
+++ b/versioned_docs/version-6.x/shared-element-transitions.md
@@ -8,11 +8,9 @@ As of writing this guide, Shared Element Transitions are considered an experimen
:::
-
-
-
-
-
+
+
+
## Pre-requisites
diff --git a/versioned_docs/version-6.x/stack-navigator.md b/versioned_docs/version-6.x/stack-navigator.md
index a8d568f2444..d35a5b73b5b 100755
--- a/versioned_docs/version-6.x/stack-navigator.md
+++ b/versioned_docs/version-6.x/stack-navigator.md
@@ -8,11 +8,9 @@ Stack Navigator provides a way for your app to transition between screens where
By default the stack navigator is configured to have the familiar iOS and Android look & feel: new screens slide in from the right on iOS, use OS default animation on Android. But the [animations can be customized](#animation-related-options) to match your needs.
-
-
-
-
-
+
+
+
One thing to keep in mind is that while `@react-navigation/stack` is extremely customizable, it's implemented in JavaScript. While it runs animations and gestures using natively, the performance may not be as fast as a native implementation. This may not be an issue for a lot of apps, but if you're experiencing performance issues during navigation, consider using [`@react-navigation/native-stack`](native-stack-navigator.md) instead - which uses native navigation primitives.
@@ -21,7 +19,7 @@ One thing to keep in mind is that while `@react-navigation/stack` is extremely c
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/stack):
```bash npm2yarn
-npm install @react-navigation/stack
+npm install @react-navigation/stack@^6.x
```
Then, you need to install and configure the libraries that are required by the stack navigator:
@@ -40,12 +38,25 @@ Then, you need to install and configure the libraries that are required by the s
npm install react-native-gesture-handler
```
-2. To finalize installation of `react-native-gesture-handler`, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+2. To finalize the installation of `react-native-gesture-handler`, we need to conditionally import it. To do this, create 2 files:
- ```js
+ ```js title="gesture-handler.native.js"
+ // Only import react-native-gesture-handler on native platforms
import 'react-native-gesture-handler';
```
+ ```js title="gesture-handler.js"
+ // Don't import react-native-gesture-handler on web
+ ```
+
+ Now, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+
+ ```js
+ import './gesture-handler';
+ ```
+
+ Since the stack navigator doesn't use `react-native-gesture-handler` on Web, this avoids unnecessarily increasing the bundle size.
+
:::warning
If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
@@ -68,9 +79,9 @@ Then, you need to install and configure the libraries that are required by the s
4. If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
- ```bash
- npx pod-install ios
- ```
+ ```bash
+ npx pod-install ios
+ ```
## API Definition
@@ -117,10 +128,6 @@ Boolean used to indicate whether inactive screens should be detached from the vi
If you need to disable this optimization for specific screens (e.g. you want to screen to stay in view even when unfocused) [`detachPreviousScreen`](#detachpreviousscreen) option.
-#### `keyboardHandlingEnabled`
-
-If `false`, the keyboard will NOT automatically dismiss when navigating to a new screen from this screen. Defaults to `true`.
-
### Options
The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Stack.navigator` or `options` prop of `Stack.Screen`.
@@ -224,6 +231,10 @@ Interpolated styles for various parts of the card. Refer the [Animations section
Interpolated styles for various parts of the header. Refer the [Animations section](#animations) for details.
+#### `keyboardHandlingEnabled`
+
+If `false`, the keyboard will NOT automatically dismiss when navigating to a new screen from this screen. Defaults to `true`.
+
#### `detachPreviousScreen`
Boolean used to indicate whether to detach the previous screen from the view hierarchy to save memory. Set it to `false` if you need the previous screen to be seen through the active screen. Only applicable if `detachInactiveScreens` isn't set to `false`.
@@ -324,8 +335,8 @@ return (
Specifies how the header should be rendered:
-- `float` - Render a single header that stays at the top and animates as screens are changed. This is default on iOS.
-- `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is default on other platforms.
+- `float` - The header is rendered above the screen and animates independently of the screen. This is default on iOS for non-modals.
+- `screen` - The header is rendered as part of the screen and animates together with the screen. This is default on other platforms.
#### `headerShown`
diff --git a/versioned_docs/version-6.x/state-persistence.md b/versioned_docs/version-6.x/state-persistence.md
index 8d6c230867b..3bde677dc8a 100755
--- a/versioned_docs/version-6.x/state-persistence.md
+++ b/versioned_docs/version-6.x/state-persistence.md
@@ -72,6 +72,12 @@ export default function App() {
}
```
+:::warning
+
+It is recommended to use an [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) in your app and clear the persisted state if an error occurs. This will ensure that the app doesn't get stuck in an error state if a screen crashes.
+
+:::
+
### Development Mode
This feature is particularly useful in development mode. You can enable it selectively using the following approach:
@@ -80,7 +86,7 @@ This feature is particularly useful in development mode. You can enable it selec
const [isReady, setIsReady] = React.useState(__DEV__ ? false : true);
```
-While it can be used for production as well, use it with caution as it can make the app unusable if the app is crashing on a particular screen - as the user will still be on the same screen after restarting.
+While it can be used for production as well, use it with caution as it can make the app unusable if the app is crashing on a particular screen - as the user will still be on the same screen after restarting. So if you are using it in production, make sure to clear the persisted state if an error occurs.
### Loading View
@@ -94,6 +100,6 @@ if (!isReady) {
## Warning: Serializable State
-Each param, route, and navigation state must be fully serializable for this feature to work. Typically, you would serialize the state as a JSON string. This means that your routes and params must contain no functions, class instances, or recursive data structures. React Navigation already [warns you during development](troubleshooting.md#i-get-the-warning-"non-serializable-values-were-found-in-the-navigation-state") if it encounters non-serializable data, so watch out for the warning if you plan to persist navigation state.
+Each param, route, and navigation state must be fully serializable for this feature to work. Typically, you would serialize the state as a JSON string. This means that your routes and params must contain no functions, class instances, or recursive data structures. React Navigation already [warns you during development](troubleshooting.md#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state) if it encounters non-serializable data, so watch out for the warning if you plan to persist navigation state.
You can modify the initial state object before passing it to container, but note that if your `initialState` isn't a [valid navigation state](navigation-state.md#partial-state-objects), React Navigation may not be able to handle the situation gracefully.
diff --git a/versioned_docs/version-6.x/status-bar.md b/versioned_docs/version-6.x/status-bar.md
index c24aaf19ffd..07614540ac4 100755
--- a/versioned_docs/version-6.x/status-bar.md
+++ b/versioned_docs/version-6.x/status-bar.md
@@ -99,7 +99,13 @@ const styles = StyleSheet.create({
});
```
-
+
+
+
+
+
+
+
## Tabs and Drawer
@@ -180,6 +186,20 @@ function Screen2({ navigation }) {
Although not necessary, you can use the `FocusAwareStatusBar` component in the screens of the native stack navigator as well.
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
diff --git a/versioned_docs/version-6.x/tab-based-navigation.md b/versioned_docs/version-6.x/tab-based-navigation.md
index 1ddce383803..16879d033e9 100755
--- a/versioned_docs/version-6.x/tab-based-navigation.md
+++ b/versioned_docs/version-6.x/tab-based-navigation.md
@@ -11,7 +11,7 @@ This guide covers [`createBottomTabNavigator`](bottom-tab-navigator.md). You may
Before continuing, first install [`@react-navigation/bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/bottom-tabs):
```bash npm2yarn
-npm install @react-navigation/bottom-tabs
+npm install @react-navigation/bottom-tabs@^6.x
```
## Minimal example of tab-based navigation
@@ -54,6 +54,8 @@ export default function App() {
}
```
+
+
## Customizing the appearance
This is similar to how you would customize a stack navigator — there are some properties that are set when you initialize the tab navigator and others that can be customized per-screen in `options`.
@@ -114,7 +116,7 @@ Sometimes we want to add badges to some icons. You can use the [`tabBarBadge` op
```
-From UI perspective this component is ready to use, but you still need to find some way to pass down the badge count properly from somewhere else, like using [React Context](https://reactjs.org/docs/context.html), [Redux](https://redux.js.org/), [MobX](https://mobx.js.org/) or [event emitters](https://github.com/facebook/react-native/blob/master/Libraries/vendor/emitter/EventEmitter.js).
+From UI perspective this component is ready to use, but you still need to find some way to pass down the badge count properly from somewhere else, like using [React Context](https://react.dev/reference/react/useContext), [Redux](https://redux.js.org/), [MobX](https://mobx.js.org/) or [event emitters](https://github.com/facebook/react-native/blob/master/Libraries/vendor/emitter/EventEmitter.js).

@@ -147,9 +149,13 @@ function SettingsScreen({ navigation }) {
}
```
+
+
+
+
## A stack navigator for each tab
-Usually tabs don't just display one screen — for example, on your Twitter feed, you can tap on a tweet and it brings you to a new screen within that tab with all of the replies. You can think of this as there being separate navigation stacks within each tab, and that's exactly how we will model it in React Navigation.
+Often tabs don't just display one screen — for example, on your Twitter feed, you can tap on a tweet and it brings you to a new screen within that tab with all of the replies. You can think of this as there being separate navigation stacks within each tab, and that's exactly how we will model it in React Navigation.
@@ -220,14 +226,18 @@ export default function App() {
return (
-
-
+
+
);
}
```
+
+
+
+
## Why do we need a TabNavigator instead of TabBarIOS or some other component?
It's common to attempt to use a standalone tab bar component without integrating it into the navigation library you use in your app. In some cases, this works fine! You should be warned, however, that you may run into some frustrating unanticipated issues when doing this.
diff --git a/versioned_docs/version-6.x/tab-view.md b/versioned_docs/version-6.x/tab-view.md
index 904d9c974cf..78d137b11cc 100644
--- a/versioned_docs/version-6.x/tab-view.md
+++ b/versioned_docs/version-6.x/tab-view.md
@@ -262,9 +262,7 @@ When you enable lazy rendering for a screen, it will usually take some time to r
You can also pass a boolean to enable lazy for all of the scenes:
```js
-
+
```
##### `lazyPreloadDistance`
diff --git a/versioned_docs/version-6.x/testing.md b/versioned_docs/version-6.x/testing.md
index 1930583107f..eb8cc4529f2 100644
--- a/versioned_docs/version-6.x/testing.md
+++ b/versioned_docs/version-6.x/testing.md
@@ -45,9 +45,7 @@ Then we need to use this setup file in our jest config. You can add it under `se
```json
{
"preset": "react-native",
- "setupFiles": [
- "/jest/setup.js"
- ],
+ "setupFiles": ["/jest/setup.js"]
}
```
diff --git a/versioned_docs/version-6.x/themes.md b/versioned_docs/version-6.x/themes.md
index fd94b1e16cc..f397ebd5bca 100755
--- a/versioned_docs/version-6.x/themes.md
+++ b/versioned_docs/version-6.x/themes.md
@@ -77,9 +77,27 @@ You can import the default and dark themes like so:
import { DefaultTheme, DarkTheme } from '@react-navigation/native';
```
+## Keeping the native theme in sync
+
+If you're changing the theme in the app, native UI elements such as Alert, ActionSheet etc. won't reflect the new theme. You can do the following to keep the native theme in sync:
+
+```js
+React.useEffect(() => {
+ const colorScheme = theme.dark ? 'dark' : 'light';
+
+ if (Platform.OS === 'web') {
+ document.documentElement.style.colorScheme = colorScheme;
+ } else {
+ Appearance.setColorScheme(colorScheme);
+ }
+}, [theme.dark]);
+```
+
+Alternatively, you can use the [`useColorScheme`](#using-the-operating-system-preferences) hook to get the current native color scheme and update the theme accordingly.
+
## Using the operating system preferences
-On iOS 13+ and Android 10+, you can get user's preferred color scheme (`'dark'` or `'light'`) with the ([Appearance API](https://reactnative.dev/docs/appearance)).
+On iOS 13+ and Android 10+, you can get user's preferred color scheme (`'dark'` or `'light'`) with the ([`useColorScheme` hook](https://reactnative.dev/docs/usecolorscheme)).
diff --git a/versioned_docs/version-6.x/troubleshooting.md b/versioned_docs/version-6.x/troubleshooting.md
index 51436d92854..5a00ee9ab80 100755
--- a/versioned_docs/version-6.x/troubleshooting.md
+++ b/versioned_docs/version-6.x/troubleshooting.md
@@ -237,7 +237,7 @@ LogBox.ignoreLogs([
## I'm getting "Invalid hook call. Hooks can only be called inside of the body of a function component"
-This can happen when you pass a React component to an option that accepts a function returning a react element. For example, the [`headerTitle` option in native stack navigator](native-stack-navigator.md#headerTitle) expects a function returning a react element:
+This can happen when you pass a React component to an option that accepts a function returning a react element. For example, the [`headerTitle` option in native stack navigator](native-stack-navigator.md#headertitle) expects a function returning a react element:
```js
```
-This will provide type checking and intelliSense for props of the `Navigator` and `Screen` components.
+This will provide type checking and intelliSense for props of the `Navigator` and [`Screen`](screen.md) components.
:::note
@@ -88,9 +88,9 @@ If you have an `id` prop for your navigator, you can do:
type Props = NativeStackScreenProps;
```
-This allows us to type check route names and params which you're navigating using `navigate`, `push` etc. The name of the current route is necessary to type check the params in `route.params` and when you call `setParams`.
+This allows us to type check route names and params which you're navigating using `navigate`, [`push`](stack-actions.md#push) etc. The name of the current route is necessary to type check the params in `route.params` and when you call [`setParams`](navigation-actions#setparams).
-Similarly, you can import `StackScreenProps` for `@react-navigation/stack`, `DrawerScreenProps` from `@react-navigation/drawer`, `BottomTabScreenProps` from `@react-navigation/bottom-tabs` and so on.
+Similarly, you can import `StackScreenProps` from [`@react-navigation/stack`](stack-navigator.md), `DrawerScreenProps` from [`@react-navigation/drawer`](drawer-navigator.md), `BottomTabScreenProps` from [`@react-navigation/bottom-tabs`](bottom-tab-navigator.md) and so on.
Then you can use the `Props` type you defined above to annotate your component.
@@ -133,7 +133,7 @@ type ProfileScreenNavigationProp = NativeStackNavigationProp<
>;
```
-Similarly, you can import `StackNavigationProp` from `@react-navigation/stack`, `DrawerNavigationProp` from `@react-navigation/drawer`, `BottomTabNavigationProp` from `@react-navigation/bottom-tabs` etc.
+Similarly, you can import `StackNavigationProp` from [`@react-navigation/stack`](stack-navigator.md), `DrawerNavigationProp` from [`@react-navigation/drawer`](drawer-navigator.md), `BottomTabNavigationProp` from [`@react-navigation/bottom-tabs`](bottom-tab-navigator.md) etc.
To get the type for the `route` prop, we need to use the `RouteProp` type from `@react-navigation/native`:
@@ -171,7 +171,9 @@ type TabParamList = {
#### Combining navigation props
-When you nest navigators, the navigation prop of the screen is a combination of multiple navigation props. For example, if we have a tab inside a stack, the `navigation` prop will have both `jumpTo` (from the tab navigator) and `push` (from the stack navigator). To make it easier to combine types from multiple navigators, you can use the `CompositeScreenProps` type:
+When you nest navigators, the navigation prop of the screen is a combination of multiple navigation props. For example, if we have a tab inside a stack, the `navigation` prop will have both [`jumpTo`](tab-actions.md#jumpto) (from the tab navigator) and [`push`](stack-actions.md#push) (from the stack navigator). To make it easier to combine types from multiple navigators, you can use the `CompositeScreenProps` type.
+
+For example, if we have a `Profile` in a navigator, nested inside `Account` screen of a stack navigator, we can combine the types as follows:
```ts
import type { CompositeScreenProps } from '@react-navigation/native';
@@ -180,20 +182,23 @@ import type { StackScreenProps } from '@react-navigation/stack';
type ProfileScreenProps = CompositeScreenProps<
BottomTabScreenProps,
- StackScreenProps
+ StackScreenProps
>;
```
-The `CompositeScreenProps` type takes 2 parameters, first parameter is the type of props for the primary navigation (type for the navigator that owns this screen, in our case the tab navigator which contains the `Profile` screen) and second parameter is the type of props for secondary navigation (type for a parent navigator). The primary type should always have the screen's route name as its second parameter.
+The `CompositeScreenProps` type takes 2 parameters:
+
+- The first parameter is the type for the navigator that owns this screen, in our case the tab navigator which contains the `Profile` screen
+- The second parameter is the type of props for a parent navigator, in our case the stack navigator which contains the `Account` screen
-For multiple parent navigators, this secondary type should be nested:
+For multiple parent navigators, this second parameter can nest another `CompositeScreenProps`:
```ts
type ProfileScreenProps = CompositeScreenProps<
BottomTabScreenProps,
CompositeScreenProps<
- StackScreenProps,
- DrawerScreenProps
+ StackScreenProps,
+ DrawerScreenProps
>
>;
```
@@ -207,7 +212,7 @@ import type { StackNavigationProp } from '@react-navigation/stack';
type ProfileScreenNavigationProp = CompositeNavigationProp<
BottomTabNavigationProp,
- StackNavigationProp
+ StackNavigationProp
>;
```
@@ -321,7 +326,7 @@ declare global {
The `RootParamList` interface lets React Navigation know about the params accepted by your root navigator. Here we extend the type `RootStackParamList` because that's the type of params for our stack navigator at the root. The name of this type isn't important.
-Specifying this type is important if you heavily use `useNavigation`, `Link` etc. in your app since it'll ensure type-safety. It will also make sure that you have correct nesting on the `linking` prop.
+Specifying this type is important if you heavily use `useNavigation`, [`Link`](link.md) etc. in your app since it'll ensure type-safety. It will also make sure that you have correct nesting on the [`linking`](navigation-container.md#linking) prop.
### Organizing types
@@ -358,7 +363,7 @@ export type HomeTabParamList = {
export type HomeTabScreenProps =
CompositeScreenProps<
BottomTabScreenProps,
- RootStackScreenProps
+ RootStackScreenProps
>;
declare global {
diff --git a/versioned_docs/version-6.x/upgrading-from-5.x.md b/versioned_docs/version-6.x/upgrading-from-5.x.md
index d8191103ce4..47c5099f8d6 100755
--- a/versioned_docs/version-6.x/upgrading-from-5.x.md
+++ b/versioned_docs/version-6.x/upgrading-from-5.x.md
@@ -136,7 +136,7 @@ These following changes are in the core library. You'll need to address this cha
To install the 6.x version of `@react-navigation/native`, run:
```bash npm2yarn
-npm install @react-navigation/native
+npm install @react-navigation/native@^6.x
```
### Params are now overwritten on navigation instead of merging
@@ -335,7 +335,7 @@ The following changes are in the `@react-navigation/stack` package.
To install the 6.x version of `@react-navigation/stack`, run:
```bash npm2yarn
-npm install @react-navigation/stack
+npm install @react-navigation/stack@^6.x
```
### `keyboardHandlingEnabled` is moved to options
@@ -395,11 +395,11 @@ The `headerMode` option supports 2 values: `screen` and `float`.
### Header is now taller in modals on iOS
-The header is now 56dp tall in modals to match the native iOS style. If you are using the [`useHeaderHeight`](elements.md#use-header-height) hook to get the height of the header, then you won't need to change any code.
+The header is now 56dp tall in modals to match the native iOS style. If you are using the [`useHeaderHeight`](elements.md#useheaderheight) hook to get the height of the header, then you won't need to change any code.
### The header height from hidden header is now ignored
-Previously, the [`useHeaderHeight`](elements.md#use-header-height) hook returned `0` if the header was hidden in a Stack Navigator. Now it returns the height of the closes visible header instead.
+Previously, the [`useHeaderHeight`](elements.md#useheaderheight) hook returned `0` if the header was hidden in a Stack Navigator. Now it returns the height of the closes visible header instead.
### Custom header now uses 'headerMode: screen' by default
@@ -451,7 +451,7 @@ The `@react-navigation/native-stack` package is back. We made few changes to the
To install the 6.x version of `@react-navigation/native-stack`, run:
```bash npm2yarn
-npm install @react-navigation/native-stack
+npm install @react-navigation/native-stack@^6.x
```
### Breaking changes from `react-native-screens/native-stack`
@@ -491,7 +491,7 @@ The following changes are in the `@react-navigation/bottom-tabs` package.
To install the 6.x version of `@react-navigation/bottom-tabs`, run:
```bash npm2yarn
-npm install @react-navigation/bottom-tabs
+npm install @react-navigation/bottom-tabs@^6.x
```
### A header is shown by default in tab screens
@@ -548,7 +548,7 @@ The following changes are in the `@react-navigation/material-top-tabs` package.
To install the 6.x version of `@react-navigation/material-top-tabs`, run:
```bash npm2yarn
-npm install @react-navigation/material-top-tabs react-native-tab-view
+npm install @react-navigation/material-top-tabs@^6.x react-native-tab-view
```
To upgrade `react-native-pager-view` to the latest supported version, do the following:
@@ -611,7 +611,7 @@ The following changes are in the `@react-navigation/material-bottom-tabs` packag
To install the 6.x version of `@react-navigation/material-bottom-tabs`, run:
```bash npm2yarn
-npm install @react-navigation/material-bottom-tabs
+npm install @react-navigation/material-bottom-tabs@^6.x
```
### Material Bottom Tabs now uses `react-native-safe-area-context` to apply safe area insets
@@ -625,7 +625,7 @@ The following changes are in the `@react-navigation/drawer` package.
To install the 6.x version of `@react-navigation/drawer`, run:
```bash npm2yarn
-npm install @react-navigation/drawer
+npm install @react-navigation/drawer@^6.x
```
### Drawer now uses Reanimated 2 if available
@@ -709,7 +709,7 @@ Similar to bottom tabs, the `lazy` prop is now moved to `options` for drawer.
We have a new package which contains various UI elements related to navigation, such as a `Header` component. This means that we can now use these components in all navigators. You can also install the library to import components such as `Header` to use in any navigator:
```bash npm2yarn
-npm install @react-navigation/elements
+npm install @react-navigation/elements@^6.x
```
Now you can import items from there:
diff --git a/versioned_docs/version-6.x/use-focus-effect.md b/versioned_docs/version-6.x/use-focus-effect.md
index e7494fa394b..c7141ae6f49 100755
--- a/versioned_docs/version-6.x/use-focus-effect.md
+++ b/versioned_docs/version-6.x/use-focus-effect.md
@@ -18,7 +18,7 @@ function Profile({ userId }) {
useFocusEffect(
React.useCallback(() => {
- const unsubscribe = API.subscribe(userId, user => setUser(user));
+ const unsubscribe = API.subscribe(userId, (user) => setUser(user));
return () => unsubscribe();
}, [userId])
@@ -107,7 +107,7 @@ useFocusEffect(
React.useCallback(() => {
return () => {
// Do something that should run on blur
- }
+ };
}, [])
);
```
@@ -116,7 +116,7 @@ The cleanup function runs whenever the effect needs to cleanup, i.e. on `blur`,
```js
React.useEffect(() => {
- const unsubscribe = navigation.addListener('blur', () => {
+ const unsubscribe = navigation.addListener('blur', () => {
// Do something when the screen blurs
});
@@ -146,7 +146,7 @@ function FetchUserData({ userId, onUpdate }) {
// ...
class Profile extends React.Component {
- _handleUpdate = user => {
+ _handleUpdate = (user) => {
// Do something with user object
};
diff --git a/versioned_docs/version-6.x/use-is-focused.md b/versioned_docs/version-6.x/use-is-focused.md
index 69ab01fdc82..c99f7561460 100755
--- a/versioned_docs/version-6.x/use-is-focused.md
+++ b/versioned_docs/version-6.x/use-is-focused.md
@@ -20,7 +20,7 @@ function Profile() {
}
```
-Note that using this hook triggers a re-render for the component when the screen it's in changes focus. This might cause lags during the animation if your component is heavy. You might want to extract the expensive parts to separate components and use [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) or [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) to minimize re-renders for them.
+Note that using this hook triggers a re-render for the component when the screen it's in changes focus. This might cause lags during the animation if your component is heavy. You might want to extract the expensive parts to separate components and use [`React.memo`](https://react.dev/reference/react/memo) or [`React.PureComponent`](https://react.dev/reference/react/PureComponent) to minimize re-renders for them.
## Using with class component
@@ -35,7 +35,7 @@ class Profile extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const isFocused = useIsFocused();
return ;
diff --git a/versioned_docs/version-6.x/use-link-props.md b/versioned_docs/version-6.x/use-link-props.md
index 4f3be40c22e..a22c0483292 100644
--- a/versioned_docs/version-6.x/use-link-props.md
+++ b/versioned_docs/version-6.x/use-link-props.md
@@ -45,7 +45,11 @@ const LinkButton = ({ to, action, children, ...rest }) => {
};
function Home() {
- return Go to Jane's profile ;
+ return (
+
+ Go to Jane's profile
+
+ );
}
```
@@ -53,7 +57,11 @@ Then you can use the `LinkButton` component elsewhere in your app:
```js
function Home() {
- return Go to Jane's profile ;
+ return (
+
+ Go to Jane's profile
+
+ );
}
```
@@ -75,9 +83,7 @@ You can pass an object with a `screen` property:
```js
function Home() {
return (
-
+
Go to Jane's profile
);
diff --git a/versioned_docs/version-6.x/use-navigation-state.md b/versioned_docs/version-6.x/use-navigation-state.md
index 59bdc9b67f3..00b3a713166 100755
--- a/versioned_docs/version-6.x/use-navigation-state.md
+++ b/versioned_docs/version-6.x/use-navigation-state.md
@@ -15,13 +15,13 @@ Consider the navigator's state object to be internal and subject to change in a
It takes a selector function as an argument. The selector will receive the full [navigation state](navigation-state.md) and can return a specific value from the state:
```js
-const index = useNavigationState(state => state.index);
+const index = useNavigationState((state) => state.index);
```
The selector function helps to reduce unnecessary re-renders, so your screen will re-render only when that's something you care about. If you actually need the whole state object, you can do this explicitly:
```js
-const state = useNavigationState(state => state);
+const state = useNavigationState((state) => state);
```
:::warning
@@ -48,7 +48,7 @@ In this example, even if you push a new screen, this text won't update. If you u
```js
function Profile() {
- const routesLength = useNavigationState(state => state.routes.length);
+ const routesLength = useNavigationState((state) => state.routes.length);
return Number of routes: {routesLength} ;
}
@@ -69,8 +69,8 @@ class Profile extends React.Component {
}
// Wrap and export
-export default function(props) {
- const routesLength = useNavigationState(state => state.routes.length);
+export default function (props) {
+ const routesLength = useNavigationState((state) => state.routes.length);
return ;
}
diff --git a/versioned_docs/version-6.x/use-navigation.md b/versioned_docs/version-6.x/use-navigation.md
index e1c4e01425b..07b9ce9d895 100755
--- a/versioned_docs/version-6.x/use-navigation.md
+++ b/versioned_docs/version-6.x/use-navigation.md
@@ -46,7 +46,7 @@ class MyBackButton extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const navigation = useNavigation();
return ;
diff --git a/versioned_docs/version-6.x/use-route.md b/versioned_docs/version-6.x/use-route.md
index 1539f343bec..1de65f7115e 100755
--- a/versioned_docs/version-6.x/use-route.md
+++ b/versioned_docs/version-6.x/use-route.md
@@ -39,7 +39,7 @@ class MyText extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const route = useRoute();
return ;
diff --git a/versioned_docs/version-6.x/use-theme.md b/versioned_docs/version-6.x/use-theme.md
index 7807e031e70..13e70d0133d 100644
--- a/versioned_docs/version-6.x/use-theme.md
+++ b/versioned_docs/version-6.x/use-theme.md
@@ -40,7 +40,7 @@ class MyButton extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const theme = useTheme();
return ;
diff --git a/versioned_docs/version-7.x/MST-integration.md b/versioned_docs/version-7.x/MST-integration.md
deleted file mode 100755
index 929f73af0f4..00000000000
--- a/versioned_docs/version-7.x/MST-integration.md
+++ /dev/null
@@ -1,82 +0,0 @@
----
-id: MST-integration
-title: Integrating with MobX State Tree
-sidebar_label: MobX State Tree integration
----
-
-:::note
-
-This guide is incomplete. Please help improve this by sending pull requests.
-
-:::
-
-This guide explores possible way to use React Navigation in a React Native project that uses [MobX State Tree](https://github.com/mobxjs/mobx-state-tree)(MST) for state management. The guide is accompanied by a [sample app](https://github.com/vonovak/react-navigation-mst-demo). Parts of the guide may be relevant also for users of [MobX](https://github.com/mobxjs/mobx) but please be aware of the fact that MobX does not come with a built-in solution for (de)serializing its state.
-
-:::note
-
-Please note that in this guide, Mobx State Tree is not used to manage the navigation state itself - just the navigation params!
-
-:::
-
-## Overview
-
-Our goal with this guide is to use MST with React Navigation and achieve optimal developer experience. In the scope of this guide, this means allowing us to do a full JS reload and be brought back to the state before the reload happened.
-
-We will do this by persisting the [navigation state](navigation-state.md) using the React Navigation's [built-in mechanism](state-persistence.md). We also need to persist the app state and navigation params - that way, when you're working on a screen in your app and do a full JS reload, you will be brought back to the same screen, with the same data in it.
-
-## Guide
-
-First, start by creating initial navigation structure and React components. When you're done with that, continue with modelling your state in MST. If you want to learn more about this, check out the [egghead.io course](https://egghead.io/lessons/react-describe-your-application-domain-using-mobx-state-tree-mst-models).
-
-At this point, you're probably wondering how to connect your MST objects with the components. The answer is in the [mobx-react package](https://github.com/mobxjs/mobx-react) that contains React bindings for MobX (they also work for MST). You will likely be using the `Provider` component and the `inject` and `observer` functions.
-
-Use `Provider` to wrap what you return from your root component's render method:
-
-```js
-
- {/* Screen configuration */}
-
-```
-
-this will allow you to access `myObject` from any React component in the application through the `inject` function which can be quite useful.
-
-Use `observer` function to wrap all components that render observable data. This will make sure the components re-render once the data they render changes.
-
-### Navigation params
-
-Screens in your application often depend on params. React Navigation allows you to [send params](params.md) from one screen to another. These params are stored in the navigation state. However, in order to persist the navigation state, it needs to be serializable. This requirement does not play well with MST, because the MST objects are complex objects and React Navigation doesn't know how to (de)serialize them. In this guide, we will work around this by storing the navigation params ourselves.
-
-This means that rather than sending the params from one screen to another (eg. with `props.navigation.navigate('MyScreen', { complexMSTObject })`) we will store the params to a navigation store, then navigate without sending any params, and on the target screen, we'll pick the params up from the navigation store.
-
-To give an example, the navigation store may look similar to this:
-
-```js
-import { types, onSnapshot, getRoot } from 'mobx-state-tree';
-import { Product } from '../models/Product';
-import { User } from '../models/User';
-
-export const NavigationStore = types
- .model('NavigationStore', {
- productDetailScreenParams: types.map(
- types.model('ProductDetailScreenParams', {
- product: types.optional(types.safeReference(Product)),
- })
- ),
- userProfileScreenParams: types.model('UserProfileScreenParams', {
- user: types.maybe(types.safeReference(User)),
- }),
- })
- .actions(self => ({
- ...
- }));
-```
-
-Note that `userProfileScreenParams` is a simple model with a `user` entry, while `productDetailScreenParams` is a map of `ProductDetailScreenParams` model. The reason we chose this shape of data is that we only have a single user profile screen in our app which reads its params from `userProfileScreenParams`. `productDetailScreenParams` is a map because the app can have several product screens on a stack. Each screen points to a `Product` instance saved in the map. The keys into the map are the React Navigation [keys](navigation-state.md): think of the `key` as of an identifier of the route.
-
-Your navigation store may also be just one map where for each screen (regardless if it is a product or user profile screen), we store its navigation params. This is the approach taken in the [sample app](https://github.com/vonovak/react-navigation-mst-demo).
-
-## Summary
-
-- you can use React Navigation with MobX State Tree in a React Native app
-- use the `Provider` component and the `inject` and `observer` functions to wire up MobX or MST with React
-- it's possible to persist the entire application state and restore it upon JS reload
diff --git a/versioned_docs/version-7.x/auth-flow.md b/versioned_docs/version-7.x/auth-flow.md
index fcda2f03faa..c3d4e71772a 100755
--- a/versioned_docs/version-7.x/auth-flow.md
+++ b/versioned_docs/version-7.x/auth-flow.md
@@ -4,6 +4,9 @@ title: Authentication flows
sidebar_label: Authentication flows
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Most apps require that a user authenticates in some way to have access to data associated with a user or other private content. Typically the flow will look like this:
- The user opens the app.
@@ -19,48 +22,169 @@ We say "authentication screens" because usually there is more than one. You may
## What we need
-This is the behavior that we want from the authentication flow: when users sign in, we want to throw away the state of the authentication flow and unmount all of the screens related to authentication, and when we press the hardware back button, we expect to not be able to go back to the authentication flow.
+We want the following behavior from our authentication flow:
+
+- When the user is signed in, we want to show the main app screens and not the authentication-related screens.
+- When the user is signed out, we want to show the authentication screens and not the main app screens.
+- After the user goes through the authentication flow and signs in, we want to unmount all of the screens related to authentication, and when we press the hardware back button, we expect to not be able to go back to the authentication flow.
## How it will work
-We can define different screens based on some condition. For example, if the user is signed in, we can define `Home`, `Profile`, `Settings` etc. If the user is not signed in, we can define `SignIn` and `SignUp` screens.
+We can configure different screens to be available based on some condition. For example, if the user is signed in, we want `Home` to be available. If the user is not signed in, we want `SignIn` to be available.
+
+
+
+
+```js name="Authentication flow" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const useIsSignedIn = () => {
+ return true;
+};
+
+const useIsSignedOut = () => {
+ return !useIsSignedIn();
+};
+
+// codeblock-focus-start
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ if: useIsSignedIn,
+ screen: HomeScreen,
+ },
+ SignIn: {
+ if: useIsSignedOut,
+ screen: SignInScreen,
+ },
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+
+function HomeScreen() {
+ return ;
+}
+
+function SignInScreen() {
+ return ;
+}
+```
+
+Here, for each screen, we have defined a condition using the `if` property which takes a hook. The hook returns a boolean value indicating whether the user is signed in or not. If the hook returns `true`, the screen will be available, otherwise it won't.
+
+This means:
+
+- When `useIsSignedIn` returns `true`, React Navigation will only use the `Home` screen, since it's the only screen matching the condition.
+- Similarly, when `useIsSignedOut` returns `true`, React Navigation will use the `SignIn` screen.
+
+This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in.
+
+When the values returned by `useIsSignedin` and `useIsSignedOut` change, the screens matching the condition will change:
+
+- Let's say, initially `useIsSignedOut` returns `true`. This means that `SignIn` screens is shown.
+- After the user signs in, the return value of `useIsSignedIn` will change to `true` and `useIsSignedOut` will change to `false`, which means:
+ - React Navigation will see that the `SignIn` screen is no longer matches the condition, so it will remove the screen.
+ - Then it'll show the `Home` screen automatically because that's the first screen available when `useIsSignedIn` returns `true`.
+
+The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens matching `useIsSignedIn`, the first screen will be shown when the condition is `true`.
-For example:
+## Define the hooks
-
+To implement the `useIsSignedIn` and `useIsSignedOut` hooks, we can start by creating a context to store the authentication state. Let's call it `SignInContext`:
```js
-isSignedIn ? (
- <>
-
-
-
- >
-) : (
- <>
-
-
- >
-);
+import * as React from 'react';
+
+const SignInContext = React.createContext();
```
-When we define screens like this, when `isSignedIn` is `true`, React Navigation will only see the `Home`, `Profile` and `Settings` screens, and when it's `false`, React Navigation will see the `SignIn` and `SignUp` screens. This makes it impossible to navigate to the `Home`, `Profile` and `Settings` screens when the user is not signed in, and to `SignIn` and `SignUp` screens when the user is signed in.
+Then we can implement the `useIsSignedIn` and `useIsSignedOut` hooks as follows:
-This pattern has been in use by other routing libraries such as React Router for a long time, and is commonly known as "Protected routes". Here, our screens which need the user to be signed in are "protected" and cannot be navigated to by other means if the user is not signed in.
+```js
+function useIsSignedIn() {
+ const isSignedIn = React.useContext(SignInContext);
+ return isSignedIn;
+}
-The magic happens when the value of the `isSignedIn` variable changes. Let's say, initially `isSignedIn` is `false`. This means, either `SignIn` or `SignUp` screens are shown. After the user signs in, the value of `isSignedIn` will change to `true`. React Navigation will see that the `SignIn` and `SignUp` screens are no longer defined and so it will remove them. Then it'll show the `Home` screen automatically because that's the first screen defined when `isSignedIn` is `true`.
+function useIsSignedOut() {
+ return !useIsSignedIn();
+}
+```
-The example shows stack navigator, but you can use the same approach with any navigator.
+We'll discuss how to provide the context value later.
-By conditionally defining different screens based on a variable, we can implement auth flow in a simple way that doesn't require additional logic to make sure that the correct screen is shown.
+
-## Don't manually navigate when conditionally rendering screens
+
-It's important to note that when using such a setup, you **don't manually navigate** to the `Home` screen by calling `navigation.navigate('Home')` or any other method. **React Navigation will automatically navigate to the correct screen** when `isSignedIn` changes - `Home` screen when `isSignedIn` becomes `true`, and to `SignIn` screen when `isSignedIn` becomes `false`. You'll get an error if you attempt to navigate manually.
+```js name="Authentication flow" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+export default function App() {
+ const isSignedIn = true;
-## Define our screens
+ return (
+
+
+ // codeblock-focus-start
+ {isSignedIn ? (
+
+ ) : (
+
+ )}
+ // codeblock-focus-end
+
+
+ );
+}
+
+function HomeScreen() {
+ return ;
+}
+
+function SignInScreen() {
+ return ;
+}
+```
+
+Here, we have conditionally defined the screens based on the value of `isSignedIn`.
+
+This means:
+
+- When `isSignedIn` is `true`, React Navigation will only see the `Home` screen, since it's the only screen defined based on the condition.
+- Similarly, when `isSignedIn` is `false`, React Navigation will only see the `SignIn` screen.
+
+This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in.
+
+When the value of `isSignedin` changes, the screens defined based on the condition will change:
+
+- Let's say, initially `isSignedin` is `false`. This means that `SignIn` screens is shown.
+- After the user signs in, the value of `isSignedin` will change to `true`, which means:
+ - React Navigation will see that the `SignIn` screen is no longer defined, so it will remove the screen.
+ - Then it'll show the `Home` screen automatically because that's the first screen defined when `isSignedin` returns `true`.
+
+The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens defined based on `isSignedin`, the first screen will be shown when the condition is `true`.
+
+
+
-In our navigator, we can conditionally define appropriate screens. For our case, let's say we have 3 screens:
+## Add more screens
+
+For our case, let's say we have 3 screens:
- `SplashScreen` - This will show a splash or loading screen when we're restoring the token.
- `SignIn` - This is the screen we show if the user isn't signed in already (we couldn't find a token).
@@ -68,47 +192,161 @@ In our navigator, we can conditionally define appropriate screens. For our case,
So our navigator will look like:
-
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ if: useIsSignedIn,
+ screen: HomeScreen,
+ },
+ SignIn: {
+ if: useIsSignedOut,
+ screen: SignInScreen,
+ options: {
+ title: 'Sign in',
+ },
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+export default function App() {
+ const isSignedIn = true;
+
+ return (
+
+
+ {isSignedIn ? (
+
+ ) : (
+
+ )}
+
+
+ );
+}
+```
+
+
+
+
+Notice how we have only defined the `Home` and `SignIn` screens here, and not the `SplashScreen`. The `SplashScreen` should be rendered before we render any navigators so that we don't render incorrect screens before we know whether the user is signed in or not.
+
+When we use this in our component, it'd look something like this:
+
+
+
```js
-if (state.isLoading) {
+if (isLoading) {
// We haven't finished checking for the token yet
return ;
}
+const isSignedIn = userToken != null;
+
return (
-
- {state.userToken == null ? (
- // No token found, user isn't signed in
-
- ) : (
- // User is signed in
-
- )}
-
+
+
+
);
```
-In the above snippet, `isLoading` means that we're still checking if we have a token. This can usually be done by checking if we have a token in `SecureStore` and validating the token. After we get the token and if it's valid, we need to set the `userToken`. We also have another state called `isSignout` to have a different animation on sign out.
+
+
-The main thing to notice is that we're conditionally defining screens based on these state variables:
+```js
+if (isLoading) {
+ // We haven't finished checking for the token yet
+ return ;
+}
-- `SignIn` screen is only defined if `userToken` is `null` (user is not signed in)
-- `Home` screen is only defined if `userToken` is non-null (user is signed in)
+const isSignedIn = userToken != null;
-Here, we're conditionally defining one screen for each case. But you could also define multiple screens. For example, you probably want to define password reset, signup, etc screens as well when the user isn't signed in. Similarly, for the screens accessible after signing in, you probably have more than one screen. We can use `React.Fragment` to define multiple screens:
+return (
+
+
+ {isSignedIn ? (
+
+ ) : (
+
+ )}
+
+
+);
+```
+
+
+
+
+In the above snippet, `isLoading` means that we're still checking if we have a token. This can usually be done by checking if we have a token in `SecureStore` and validating the token.
+
+Next, we're exposing the sign in status via the `SignInContext` so that it's available to the `useIsSignedIn` and `useIsSignedOut` hooks.
+
+In the above example, we have one screen for each case. But you could also define multiple screens. For example, you probably want to define password reset, signup, etc screens as well when the user isn't signed in. Similarly for the screens accessible after sign in, you probably have more than one screen.
+
+
+
+
+We can use [`groups`](static-configuration.md#groups) to define multiple screens:
```js
-state.userToken == null ? (
+const RootStack = createNativeStackNavigator({
+ screens: {
+ // Common screens
+ },
+ groups: {
+ SignedIn: {
+ if: useIsSignedIn,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+ },
+ SignedOut: {
+ if: useIsSignedOut,
+ screens: {
+ SignIn: SignInScreen,
+ SignUp: SignUpScreen,
+ ResetPassword: ResetPasswordScreen,
+ },
+ },
+ },
+});
+```
+
+
+
+
+We can use [`React.Fragment`](https://react.dev/reference/react/Fragment) or [`Group`](group.md) to define multiple screens:
+
+```js
+isSignedIn ? (
<>
@@ -124,10 +362,13 @@ state.userToken == null ? (
:::tip
-If you have both your login-related screens and rest of the screens in two different Stack navigators, we recommend to use a single Stack navigator and place the conditional inside instead of using 2 different navigators. This makes it possible to have a proper transition animation during login/logout.
+Instead of having your login-related screens and rest of the screens in two different Stack navigators and render them conditionally, we recommend to use a single Stack navigator and place the conditional inside. This makes it possible to have a proper transition animation during login/logout.
:::
+
+
+
## Implement the logic for restoring the token
:::note
@@ -138,8 +379,8 @@ The following is just an example of how you might implement the logic for authen
From the previous snippet, we can see that we need 3 state variables:
-- `isLoading` - We set this to `true` when we're trying to check if we already have a token saved in `SecureStore`
-- `isSignout` - We set this to `true` when user is signing out, otherwise set it to `false`
+- `isLoading` - We set this to `true` when we're trying to check if we already have a token saved in `SecureStore`.
+- `isSignout` - We set this to `true` when user is signing out, otherwise set it to `false`. This can be used to customize the animation when signing out.
- `userToken` - The token for the user. If it's non-null, we assume the user is logged in, otherwise not.
So we need to:
@@ -149,7 +390,7 @@ So we need to:
We'll use `React.useReducer` and `React.useContext` in this guide. But if you're using a state management library such as Redux or Mobx, you can use them for this functionality instead. In fact, in bigger apps, a global state management library is more suitable for storing authentication tokens. You can adapt the same approach to your state management library.
-First we'll need to create a context for auth where we can expose necessary methods:
+First we'll need to create a context for auth where we can expose the necessary methods:
```js
import * as React from 'react';
@@ -164,14 +405,78 @@ In our component, we will:
- Expose the methods for sign in and sign out to child components using `AuthContext`
So our component will look like this:
+
+
-
-
-```js
+```js name="Signing in and signing out with AuthContext" snack dependencies=expo-secure-store
+// codeblock-focus-start
import * as React from 'react';
import * as SecureStore from 'expo-secure-store';
-export default function App({ navigation }) {
+// codeblock-focus-end
+import { Text, TextInput, View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+const AuthContext = React.createContext();
+
+const SignInContext = React.createContext();
+
+function useIsSignedIn() {
+ const isSignedIn = React.useContext(SignInContext);
+ return isSignedIn;
+}
+
+function useIsSignedOut() {
+ return !useIsSignedIn();
+}
+
+function SplashScreen() {
+ return (
+
+ Loading...
+
+ );
+}
+
+function HomeScreen() {
+ const { signOut } = React.useContext(AuthContext);
+
+ return (
+
+ Signed in!
+ Sign out
+
+ );
+}
+
+function SignInScreen() {
+ const [username, setUsername] = React.useState('');
+ const [password, setPassword] = React.useState('');
+
+ const { signIn } = React.useContext(AuthContext);
+
+ return (
+
+
+
+ signIn({ username, password })}>Sign in
+
+ );
+}
+
+// codeblock-focus-start
+export default function App() {
const [state, dispatch] = React.useReducer(
(prevState, action) => {
switch (action.type) {
@@ -208,13 +513,13 @@ export default function App({ navigation }) {
let userToken;
try {
+ // Restore token stored in `SecureStore` or any other encrypted storage
userToken = await SecureStore.getItemAsync('userToken');
} catch (e) {
// Restoring token failed
}
// After restoring token, we may need to validate it in production apps
- // ...
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
@@ -229,7 +534,7 @@ export default function App({ navigation }) {
signIn: async (data) => {
// In a production app, we need to send some data (usually username, password) to server and get a token
// We will also need to handle errors if sign in failed
- // After getting token, we need to persist the token using `SecureStore`
+ // After getting token, we need to persist the token using `SecureStore` or any other encrypted storage
// In the example, we'll use a dummy token
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
@@ -238,7 +543,7 @@ export default function App({ navigation }) {
signUp: async (data) => {
// In a production app, we need to send user data to server and get a token
// We will also need to handle errors if sign up failed
- // After getting token, we need to persist the token using `SecureStore`
+ // After getting token, we need to persist the token using `SecureStore` or any other encrypted storage
// In the example, we'll use a dummy token
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
@@ -248,23 +553,212 @@ export default function App({ navigation }) {
);
if (state.isLoading) {
+ // We haven't finished checking for the token yet
return ;
}
+ const isSignedIn = state.userToken != null;
+
return (
-
- {state.userToken == null ? (
-
- ) : (
-
- )}
-
+
+
+
);
}
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ if: useIsSignedIn,
+ screen: HomeScreen,
+ },
+ SignIn: {
+ if: useIsSignedOut,
+ screen: SignInScreen,
+ options: {
+ title: 'Sign in',
+ },
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+// codeblock-focus-end
```
+
+
+
+```js name="Signing in and signing out with AuthContext" snack dependencies=expo-secure-store
+// codeblock-focus-start
+import * as React from 'react';
+import * as SecureStore from 'expo-secure-store';
+
+// codeblock-focus-end
+import { Text, TextInput, View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+const AuthContext = React.createContext();
+
+function SplashScreen() {
+ return (
+
+ Loading...
+
+ );
+}
+
+function HomeScreen() {
+ const { signOut } = React.useContext(AuthContext);
+
+ return (
+
+ Signed in!
+ Sign out
+
+ );
+}
+
+function SignInScreen() {
+ const [username, setUsername] = React.useState('');
+ const [password, setPassword] = React.useState('');
+
+ const { signIn } = React.useContext(AuthContext);
+
+ return (
+
+
+
+ signIn({ username, password })}>Sign in
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+// codeblock-focus-start
+export default function App() {
+ const [state, dispatch] = React.useReducer(
+ (prevState, action) => {
+ switch (action.type) {
+ case 'RESTORE_TOKEN':
+ return {
+ ...prevState,
+ userToken: action.token,
+ isLoading: false,
+ };
+ case 'SIGN_IN':
+ return {
+ ...prevState,
+ isSignout: false,
+ userToken: action.token,
+ };
+ case 'SIGN_OUT':
+ return {
+ ...prevState,
+ isSignout: true,
+ userToken: null,
+ };
+ }
+ },
+ {
+ isLoading: true,
+ isSignout: false,
+ userToken: null,
+ }
+ );
+
+ React.useEffect(() => {
+ // Fetch the token from storage then navigate to our appropriate place
+ const bootstrapAsync = async () => {
+ let userToken;
+
+ try {
+ // Restore token stored in `SecureStore` or any other encrypted storage
+ userToken = await SecureStore.getItemAsync('userToken');
+ } catch (e) {
+ // Restoring token failed
+ }
+
+ // After restoring token, we may need to validate it in production apps
+
+ // This will switch to the App screen or Auth screen and this loading
+ // screen will be unmounted and thrown away.
+ dispatch({ type: 'RESTORE_TOKEN', token: userToken });
+ };
+
+ bootstrapAsync();
+ }, []);
+
+ const authContext = React.useMemo(
+ () => ({
+ signIn: async (data) => {
+ // In a production app, we need to send some data (usually username, password) to server and get a token
+ // We will also need to handle errors if sign in failed
+ // After getting token, we need to persist the token using `SecureStore` or any other encrypted storage
+ // In the example, we'll use a dummy token
+
+ dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
+ },
+ signOut: () => dispatch({ type: 'SIGN_OUT' }),
+ signUp: async (data) => {
+ // In a production app, we need to send user data to server and get a token
+ // We will also need to handle errors if sign up failed
+ // After getting token, we need to persist the token using `SecureStore` or any other encrypted storage
+ // In the example, we'll use a dummy token
+
+ dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
+ },
+ }),
+ []
+ );
+
+ return (
+
+
+
+ {state.isLoading ? (
+ // We haven't finished checking for the token yet
+
+ ) : state.userToken == null ? (
+ // No token found, user isn't signed in
+
+ ) : (
+ // User is signed in
+
+ )}
+
+
+
+ );
+}
+// codeblock-focus-end
+```
+
+
+
+
## Fill in other components
We won't talk about how to implement the text inputs and buttons for the authentication screen, that is outside of the scope of navigation. We'll just fill in some placeholder content.
@@ -289,7 +783,7 @@ function SignInScreen() {
onChangeText={setPassword}
secureTextEntry
/>
- signIn({ username, password })} />
+ signIn({ username, password })}>Sign in
);
}
@@ -301,6 +795,36 @@ You can similarly fill in the other screens according to your requirements.
Consider the following example:
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ groups: {
+ LoggedIn: {
+ if: useIsSignedIn,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+ },
+ LoggedOut: {
+ if: useIsSignedOut,
+ screens: {
+ SignIn: SignInScreen,
+ SignUp: SignUpScreen,
+ },
+ },
+ },
+ screens: {
+ Help: HelpScreen,
+ },
+});
+```
+
+
+
+
```js
isSignedIn ? (
<>
@@ -317,11 +841,49 @@ isSignedIn ? (
);
```
-Here we have specific screens such as `SignIn`, `Home` etc. which are only shown depending on the sign in state. But we also have the `Help` screen which can be shown in both cases. This also means that if the signin state changes when the user is in the `Help` screen, they'll stay on the `Help` screen.
+
+
+
+Here we have specific screens such as `SignIn`, `Home` etc. which are only shown depending on the sign in state. But we also have the `Help` screen which can be shown regardless of the login status. This also means that if the sign in state changes when the user is in the `Help` screen, they'll stay on the `Help` screen.
+
+This can be a problem, we probably want the user to be taken to the `SignIn` screen or `Home` screen instead of keeping them on the `Help` screen.
+
+
+
-This can be a problem, we probably want the user to be taken to the `SignIn` screen or `Home` screen instead of keeping them on the `Help` screen. To make this work, we can use the [`navigationKey` prop](screen.md#navigationkey). When the `navigationKey` changes, React Navigation will remove all the screen.
+To make this work, we can move the `Help` screen to both of the groups instead of keeping it outside. This will ensure that the [`navigationKey`](screen.md#navigation-key) (the name of the group) for the screen changes when the sign in state changes.
-So our updated code will look like following:
+So our updated code will look like the following:
+
+```js
+const RootStack = createNativeStackNavigator({
+ groups: {
+ LoggedIn: {
+ if: useIsSignedIn,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ Help: HelpScreen,
+ },
+ },
+ LoggedOut: {
+ if: useIsSignedOut,
+ screens: {
+ SignIn: SignInScreen,
+ SignUp: SignUpScreen,
+ Help: HelpScreen,
+ },
+ },
+ },
+});
+```
+
+
+
+
+To make this work, we can use [`navigationKey`](screen.md#navigation-key). When the `navigationKey` changes, React Navigation will remove all the screen.
+
+So our updated code will look like the following:
```js
<>
@@ -344,7 +906,7 @@ So our updated code will look like following:
>
```
-If you have a bunch of shared screens, you can also use [`navigationKey` with a `Group`](group.md#navigationkey) to remove all of the screens in the group. For example:
+If you have a bunch of shared screens, you can also use [`navigationKey` with a `Group`](group.md#navigation-key) to remove all of the screens in the group. For example:
```js
<>
@@ -365,3 +927,76 @@ If you have a bunch of shared screens, you can also use [`navigationKey` with a
>
```
+
+
+
+
+The examples above show stack navigator, but you can use the same approach with any navigator.
+
+By specifying a condition for our screens, we can implement auth flow in a simple way that doesn't require additional logic to make sure that the correct screen is shown.
+
+## Don't manually navigate when conditionally rendering screens
+
+It's important to note that when using such a setup, you **don't manually navigate** to the `Home` screen by calling `navigation.navigate('Home')` or any other method. **React Navigation will automatically navigate to the correct screen** when `isSignedIn` changes - `Home` screen when `isSignedIn` becomes `true`, and to `SignIn` screen when `isSignedIn` becomes `false`. You'll get an error if you attempt to navigate manually.
+
+## Handling deep links after auth
+
+When using deep links, you may want to handle the case where the user opens a deep link that requires authentication.
+
+Example scenario:
+
+- User opens a deep link to `myapp://profile` but is not signed in.
+- The app shows the `SignIn` screen.
+- After the user signs in, you want to navigate them to the `Profile` screen.
+
+To achieve this, you can set [`UNSTABLE_routeNamesChangeBehavior`](navigator.md#route-names-change-behavior) to `"lastUnhandled"`:
+
+:::warning
+
+This API is experimental and may change in a minor release.
+
+:::
+
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ // highlight-next-line
+ UNSTABLE_routeNamesChangeBehavior: 'lastUnhandled',
+ screens: {
+ Home: {
+ if: useIsSignedIn,
+ screen: HomeScreen,
+ },
+ SignIn: {
+ if: useIsSignedOut,
+ screen: SignInScreen,
+ options: {
+ title: 'Sign in',
+ },
+ },
+ },
+});
+```
+
+
+
+
+```js
+
+ {isSignedIn ? (
+
+ ) : (
+
+ )}
+
+```
+
+
+
+
+The `UNSTABLE_routeNamesChangeBehavior` option allows you to control how React Navigation handles navigation when the available screens change because of conditions such as authentication state. When `lastUnhandled` is specified, React Navigation will remember the last screen that couldn't be handled, and after the condition changes, it'll automatically navigate to that screen if it's now available.
diff --git a/versioned_docs/version-7.x/bottom-tab-navigator.md b/versioned_docs/version-7.x/bottom-tab-navigator.md
index 849306b74f1..574ffc16b34 100755
--- a/versioned_docs/version-7.x/bottom-tab-navigator.md
+++ b/versioned_docs/version-7.x/bottom-tab-navigator.md
@@ -6,18 +6,16 @@ sidebar_label: Bottom Tabs
A simple tab bar on the bottom of the screen that lets you switch between different routes. Routes are lazily initialized -- their screen components are not mounted until they are first focused.
-
-
-
-
-
+
+
+
## Installation
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/bottom-tabs):
```bash npm2yarn
-npm install @react-navigation/bottom-tabs@next
+npm install @react-navigation/bottom-tabs
```
## Usage
@@ -27,10 +25,14 @@ To use this navigator, import it from `@react-navigation/bottom-tabs`:
-```js name="Bottom Tab Navigator" snack version=7
+```js name="Bottom Tab Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
-import { createStaticNavigation, useNavigation } from '@react-navigation/native';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
@@ -41,10 +43,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -55,10 +56,7 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Home')}
- />
+ navigation.navigate('Home')}>Go to Home
);
}
@@ -82,10 +80,11 @@ export default function App() {
-```js name="Bottom Tab Navigator" snack version=7
+```js name="Bottom Tab Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
@@ -107,10 +106,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -121,10 +119,7 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Home')}
- />
+ navigation.navigate('Home')}>Go to Home
);
}
@@ -141,29 +136,11 @@ export default function App() {
-:::note
-
-For a complete usage guide see [Tab Navigation](tab-based-navigation.md).
-
-:::
-
## API Definition
### Props
-The `Tab.Navigator` component accepts following props:
-
-#### `id`
-
-Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator.
-
-#### `initialRouteName`
-
-The name of the route to render on first load of the navigator.
-
-#### `screenOptions`
-
-Default options to use for the screens in the navigator.
+In addition to the [common props](navigator.md#configuration) shared by all navigators, the bottom tab navigator accepts the following additional props:
#### `backBehavior`
@@ -175,28 +152,43 @@ It supports the following values:
- `initialRoute` - return to initial screen passed in `initialRouteName` prop, if not passed, defaults to the first screen
- `order` - return to screen defined before the focused screen
- `history` - return to last visited screen in the navigator; if the same screen is visited multiple times, the older entries are dropped from the history
+- `fullHistory` - return to last visited screen in the navigator; doesn't drop duplicate entries unlike `history` - this behavior is useful to match how web pages work
- `none` - do not handle back button
#### `detachInactiveScreens`
Boolean used to indicate whether inactive screens should be detached from the view hierarchy to save memory. This enables integration with [react-native-screens](https://github.com/software-mansion/react-native-screens). Defaults to `true`.
-#### `sceneContainerStyle`
-
-Style object for the component wrapping the screen content.
-
#### `tabBar`
Function that returns a React element to display as the tab bar.
-Example:
+The function receives an object containing the following properties as the argument:
-
+- `state` - The state object for the tab navigator.
+- `descriptors` - The descriptors object containing options for the tab navigator.
+- `navigation` - The navigation object for the tab navigator.
-```js
-import { View, Text, TouchableOpacity } from 'react-native';
+The `state.routes` array contains all the routes defined in the navigator. Each route's options can be accessed using `descriptors[route.key].options`.
+
+Example:
+
+```js name="Custom tab bar" snack tabs=config
+import * as React from 'react';
+import {
+ createStaticNavigation,
+ NavigationContainer,
+} from '@react-navigation/native';
+// codeblock-focus-start
+import { View, Platform } from 'react-native';
+import { useLinkBuilder, useTheme } from '@react-navigation/native';
+import { Text, PlatformPressable } from '@react-navigation/elements';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function MyTabBar({ state, descriptors, navigation }) {
+ const { colors } = useTheme();
+ const { buildHref } = useLinkBuilder();
+
return (
{state.routes.map((route, index) => {
@@ -205,8 +197,8 @@ function MyTabBar({ state, descriptors, navigation }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
@@ -218,8 +210,7 @@ function MyTabBar({ state, descriptors, navigation }) {
});
if (!isFocused && !event.defaultPrevented) {
- // The `merge: true` option makes sure that the params inside the tab screen are preserved
- navigation.navigate({ name: route.name, merge: true });
+ navigation.navigate(route.name, route.params);
}
};
@@ -231,30 +222,87 @@ function MyTabBar({ state, descriptors, navigation }) {
};
return (
-
-
+
{label}
-
+
);
})}
);
}
-// ...
+// codeblock-focus-end
+
+function HomeScreen() {
+ return (
+
+ Home Screen
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile Screen
+
+ );
+}
+
+// codeblock-tabs=static
+// codeblock-focus-start
+const MyTabs = createBottomTabNavigator({
+ // highlight-next-line
+ tabBar: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(MyTabs);
+
+export default function App() {
+ return ;
+}
+// codeblock-tabs-end
- }>
- {...}
-
+// codeblock-tabs=dynamic
+const Tab = createBottomTabNavigator();
+
+// codeblock-focus-start
+function MyTabs() {
+ return (
+ }
+ >
+
+
+
+ );
+}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+// codeblock-tabs-end
```
This example will render a basic tab bar with labels.
@@ -265,19 +313,20 @@ Note that you **cannot** use the `useNavigation` hook inside the `tabBar` since
function MyTabBar({ navigation }) {
return (
{
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
- />
+ >
+ Go somewhere
+
);
}
```
### Options
-The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Tab.navigator` or `options` prop of `Tab.Screen`.
+The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Tab.Navigator` or `options` prop of `Tab.Screen`.
#### `title`
@@ -295,14 +344,28 @@ Whether the tab label should be visible. Defaults to `true`.
Whether the label is shown below the icon or beside the icon.
+By default, the position is chosen automatically based on device width.
+
- `below-icon`: the label is shown below the icon (typical for iPhones)
-- `beside-icon` the label is shown next to the icon (typical for iPad)
+
-By default, the position is chosen automatically based on device width.
+- `beside-icon` the label is shown next to the icon (typical for iPad)
+
#### `tabBarLabelStyle`
Style object for the tab label.
+
+
+Example:
+
+```js
+ tabBarLabelStyle: {
+ fontSize: 16,
+ fontFamily: 'Georgia',
+ fontWeight: 300,
+ },
+```
#### `tabBarIcon`
@@ -316,17 +379,26 @@ Style object for the tab icon.
Text to show in a badge on the tab icon. Accepts a `string` or a `number`.
+
+
#### `tabBarBadgeStyle`
Style for the badge on the tab icon. You can specify a background color or text color here.
-#### `tabBarAccessibilityLabel`
+
-Accessibility label for the tab button. This is read by the screen reader when the user taps the tab. It's recommended to set this if you don't have a label for the tab.
+Example:
-#### `tabBarTestID`
+```js
+ tabBarBadgeStyle: {
+ color: 'black',
+ backgroundColor: 'yellow',
+ },
+```
-ID to locate this tab button in tests.
+#### `tabBarAccessibilityLabel`
+
+Accessibility label for the tab button. This is read by the screen reader when the user taps the tab. It's recommended to set this if you don't have a label for the tab.
#### `tabBarButton`
@@ -338,13 +410,19 @@ You can specify a custom implementation here:
tabBarButton: (props) => ;
```
+#### `tabBarButtonTestID`
+
+ID to locate this tab button in tests.
+
#### `tabBarActiveTintColor`
Color for the icon and label in the active tab.
+
#### `tabBarInactiveTintColor`
Color for the icon and label in the inactive tabs.
+
#### `tabBarActiveBackgroundColor`
@@ -376,75 +454,140 @@ To show your screen under the tab bar, you can set the `position` style to absol
>
```
-You also might need to add a bottom margin to your content if you have a absolutely positioned tab bar. React Navigation won't do it automatically.
+You also might need to add a bottom margin to your content if you have an absolutely positioned tab bar. React Navigation won't do it automatically. See [`useBottomTabBarHeight`](#usebottomtabbarheight) for more details.
-To get the height of the bottom tab bar, you can use `BottomTabBarHeightContext` with [React's Context API](https://reactjs.org/docs/context.html#contextconsumer) or `useBottomTabBarHeight`:
+#### `tabBarBackground`
+
+Function which returns a React Element to use as background for the tab bar. You could render an image, a gradient, blur view etc.:
```js
-import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
+import { BlurView } from 'expo-blur';
// ...
-
- {tabBarHeight => (
- /* render something */
- )}
-
+ (
+
+ ),
+ }}
+>
```
-or
+When using `BlurView`, make sure to set `position: 'absolute'` in `tabBarStyle` as well. You'd also need to use [`useBottomTabBarHeight`](#usebottomtabbarheight) to add bottom padding to your content.
+
+
+
+#### `tabBarPosition`
+
+Position of the tab bar. Available values are:
+
+- `bottom` (Default)
+- `top`
+- `left`
+- `right`
+
+When the tab bar is positioned on the `left` or `right`, it is styled as a sidebar. This can be useful when you want to show a sidebar on larger screens and a bottom tab bar on smaller screens:
+
+
+
```js
-import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
+const Tabs = createBottomTabNavigator({
+ screenOptions: {
+ tabBarPosition: isLargeScreen ? 'left' : 'bottom',
+ },
-// ...
+ // ...
+});
+```
-const tabBarHeight = useBottomTabBarHeight();
+
+
+
+```js
+
```
-#### `tabBarBackground`
+
+
-Function which returns a React Element to use as background for the tab bar. You could render an image, a gradient, blur view etc.:
+
+
+You can also render a compact sidebar by placing the label below the icon. This is only supported when the [`tabBarVariant`](#tabbarvariant) is set to `material`:
+
+
+
```js
-import { BlurView } from 'expo-blur';
+const Tabs = createBottomTabNavigator({
+ screenOptions: {
+ tabBarPosition: isLargeScreen ? 'left' ? 'bottom',
+ tabBarVariant: isLargeScreen ? 'material' : 'uikit',
+ tabBarLabelPosition: 'below-icon',
+ },
-// ...
+ // ...
+});
+```
+
+
+
+```js
(
-
- ),
+ tabBarPosition: dimensions.width < 600 ? 'bottom' : 'left',
+ tabBarLabelPosition: 'below-icon',
}}
>
```
-When using `BlurView`, make sure to set `position: 'absolute'` in `tabBarStyle` as well. You'd also need to use `useBottomTabBarHeight()` to add a bottom padding to your content.
+
+
-#### `lazy`
+
-Whether this screens should render the first time it's accessed. Defaults to `true`. Set it to `false` if you want to render the screen on initial render.
+#### `tabBarVariant`
-#### `unmountOnBlur`
+Variant of the tab bar. Available values are:
-Whether this screen should be unmounted when navigating away from it. Unmounting a screen resets any local state in the screen as well as state of nested navigators in the screen. Defaults to `false`.
+- `uikit` (Default) - The tab bar will be styled according to the iOS UIKit guidelines.
+- `material` - The tab bar will be styled according to the Material Design guidelines.
-Normally, we don't recommend enabling this prop as users don't expect their navigation history to be lost when switching tabs. If you enable this prop, please consider if this will actually provide a better experience for the user.
+The `material` variant is currently only supported when the [`tabBarPosition`](#tabbarposition) is set to `left` or `right`.
+
+
+
+#### `lazy`
+
+Whether this screen should render only after the first time it's accessed. Defaults to `true`. Set it to `false` if you want to render the screen on the initial render of the navigator.
#### `freezeOnBlur`
Boolean indicating whether to prevent inactive screens from re-rendering. Defaults to `false`.
Defaults to `true` when `enableFreeze()` from `react-native-screens` package is run at the top of the application.
-Requires `react-native-screens` version >=3.16.0.
-
Only supported on iOS and Android.
+#### `popToTopOnBlur`
+
+Boolean indicating whether any nested stack should be popped to the top of the stack when navigating away from this tab. Defaults to `false`.
+
+It only works when there is a stack navigator (e.g. [stack navigator](stack-navigator.md) or [native stack navigator](native-stack-navigator.md)) nested under the tab navigator.
+
+#### `sceneStyle`
+
+Style object for the component wrapping the screen content.
+
### Header related options
-You can find the list of header related options [here](elements.md#header). These [options](screen-options.md) can be specified under `screenOptions` prop of `Tab.navigator` or `options` prop of `Tab.Screen`. You don't have to be using `@react-navigation/elements` directly to use these options, they are just documented in that page.
+You can find the list of header related options [here](elements.md#header). These [options](screen-options.md) can be specified under `screenOptions` prop of `Tab.Navigator` or `options` prop of `Tab.Screen`. You don't have to be using `@react-navigation/elements` directly to use these options, they are just documented in that page.
In addition to those, the following options are also supported in bottom tabs:
@@ -559,56 +702,594 @@ Navigates to an existing screen in the tab navigator. The method accepts followi
navigation.jumpTo('Profile', { owner: 'Michaś' });
```
-## Example
+### Hooks
+
+The bottom tab navigator exports the following hooks:
+
+#### `useBottomTabBarHeight`
+
+This hook returns the height of the bottom tab bar. By default, the screen content doesn't go under the tab bar. However, if you want to make the tab bar absolutely positioned and have the content go under it (e.g. to show a blur effect), it's necessary to adjust the content to take the tab bar height into account.
+
+Example:
+
+```js
+import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
+
+function MyComponent() {
+ const tabBarHeight = useBottomTabBarHeight();
+
+ return (
+
+ {/* Content */}
+
+ );
+}
+```
-
+Alternatively, you can use the `BottomTabBarHeightContext` directly if you are using a class component or need it in a reusable component that can be used outside the bottom tab navigator:
```js
+import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
+
+// ...
+
+
+ {tabBarHeight => (
+ /* render something */
+ )}
+
+```
+
+## Animations
+
+By default, switching between tabs doesn't have any animation. You can specify the `animation` option to customize the transition animation.
+
+Supported values for `animation` are:
+
+- `fade` - Cross-fade animation for the screen transition where the new screen fades in and the old screen fades out.
+
+
+
+
+
+- `shift` - Shifting animation for the screen transition where the screens slightly shift to left/right.
+
+
+
+
+
+- `none` - The screen transition doesn't have any animation. This is the default value.
+
+
+
+
+```js name="Bottom Tabs animation" snack
+import * as React from 'react';
+import { View, Text, Easing } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
-import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile!
+
+ );
+}
+
+// codeblock-focus-start
+const RootTabs = createBottomTabNavigator({
+ screenOptions: {
+ // highlight-start
+ animation: 'fade',
+ // highlight-end
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Bottom Tabs animation" snack
+import * as React from 'react';
+import { Text, View, Easing } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile!
+
+ );
+}
const Tab = createBottomTabNavigator();
-function MyTabs() {
+// codeblock-focus-start
+function RootTabs() {
return (
- (
-
- ),
- }}
- />
- (
-
- ),
- tabBarBadge: 3,
- }}
- />
- (
-
- ),
- }}
- />
+
+
);
}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+ );
+}
```
+
+
+
+
+If you need more control over the animation, you can customize individual parts of the animation using the various animation-related options:
+
+### Animation related options
+
+Bottom Tab Navigator exposes various options to configure the transition animation when switching tabs. These transition animations can be customized on a per-screen basis by specifying the options in the `options` for each screen, or for all screens in the tab navigator by specifying them in the `screenOptions`.
+
+- `transitionSpec` - An object that specifies the animation type (`timing` or `spring`) and its options (such as `duration` for `timing`). It contains 2 properties:
+
+ - `animation` - The animation function to use for the animation. Supported values are `timing` and `spring`.
+ - `config` - The configuration object for the timing function. For `timing`, it can be `duration` and `easing`. For `spring`, it can be `stiffness`, `damping`, `mass`, `overshootClamping`, `restDisplacementThreshold` and `restSpeedThreshold`.
+
+ A config that uses a timing animation looks like this:
+
+ ```js
+ const config = {
+ animation: 'timing',
+ config: {
+ duration: 150,
+ easing: Easing.inOut(Easing.ease),
+ },
+ };
+ ```
+
+ We can pass this config in the `transitionSpec` option:
+
+
+
+
+ ```js
+ {
+ Profile: {
+ screen: Profile,
+ options: {
+ // highlight-start
+ transitionSpec: {
+ animation: 'timing',
+ config: {
+ duration: 150,
+ easing: Easing.inOut(Easing.ease),
+ },
+ },
+ // highlight-end
+ },
+ },
+ }
+ ```
+
+
+
+
+ ```js
+
+ ```
+
+
+
+
+- `sceneStyleInterpolator` - This is a function that specifies interpolated styles for various parts of the scene. It currently supports style for the view containing the screen:
+
+ - `sceneStyle` - Style for the container view wrapping the screen content.
+
+ The function receives the following properties in its argument:
+
+ - `current` - Animation values for the current screen:
+ - `progress` - Animated node representing the progress value of the current screen.
+
+ A config that fades the screen looks like this:
+
+ ```js
+ const forFade = ({ current }) => ({
+ sceneStyle: {
+ opacity: current.progress.interpolate({
+ inputRange: [-1, 0, 1],
+ outputRange: [0, 1, 0],
+ }),
+ },
+ });
+ ```
+
+ The value of `current.progress` is as follows:
+
+ - -1 if the index is lower than the active tab,
+ - 0 if they're active,
+ - 1 if the index is higher than the active tab
+
+ We can pass this function in `sceneStyleInterpolator` option:
+
+
+
+
+ ```js
+ {
+ Profile: {
+ screen: Profile,
+ options: {
+ // highlight-start
+ sceneStyleInterpolator: ({ current }) => ({
+ sceneStyle: {
+ opacity: current.progress.interpolate({
+ inputRange: [-1, 0, 1],
+ outputRange: [0, 1, 0],
+ }),
+ },
+ }),
+ // highlight-end
+ },
+ },
+ }
+ ```
+
+
+
+
+ ```js
+ ({
+ sceneStyle: {
+ opacity: current.progress.interpolate({
+ inputRange: [-1, 0, 1],
+ outputRange: [0, 1, 0],
+ }),
+ },
+ }),
+ // highlight-end
+ }}
+ />
+ ```
+
+
+
+
+Putting these together, you can customize the transition animation for a screen:
+
+
+
+
+```js name="Bottom Tabs custom animation" snack
+import * as React from 'react';
+import { View, Text, Easing } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile!
+
+ );
+}
+
+// codeblock-focus-start
+const RootTabs = createBottomTabNavigator({
+ screenOptions: {
+ transitionSpec: {
+ animation: 'timing',
+ config: {
+ duration: 150,
+ easing: Easing.inOut(Easing.ease),
+ },
+ },
+ sceneStyleInterpolator: ({ current }) => ({
+ sceneStyle: {
+ opacity: current.progress.interpolate({
+ inputRange: [-1, 0, 1],
+ outputRange: [0, 1, 0],
+ }),
+ },
+ }),
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Bottom Tabs custom animation" snack
+import * as React from 'react';
+import { Text, View, Easing } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile!
+
+ );
+}
+
+const Tab = createBottomTabNavigator();
+
+// codeblock-focus-start
+function RootTabs() {
+ return (
+ ({
+ sceneStyle: {
+ opacity: current.progress.interpolate({
+ inputRange: [-1, 0, 1],
+ outputRange: [0, 1, 0],
+ }),
+ },
+ }),
+ }}
+ >
+
+
+
+ );
+}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
+### Pre-made configs
+
+We also export various configs from the library with ready-made configs that you can use to customize the animations:
+
+#### `TransitionSpecs`
+
+- `FadeSpec` - Configuration for a cross-fade animation between screens.
+- `ShiftSpec` - Configuration for a shifting animation between screens.
+
+Example:
+
+
+
+
+```js
+import { TransitionSpecs } from '@react-navigation/bottom-tabs';
+
+// ...
+
+{
+ Profile: {
+ screen: Profile,
+ options: {
+ // highlight-start
+ transitionSpec: TransitionSpecs.CrossFadeSpec,
+ // highlight-end
+ },
+ },
+}
+```
+
+
+
+
+```js
+import { TransitionSpecs } from '@react-navigation/bottom-tabs';
+
+// ...
+
+ ;
+```
+
+
+
+
+#### `SceneStyleInterpolators`
+
+- `forFade` - Cross-fade animation for the screen transition where the new screen fades in and the old screen fades out.
+- `forShift` - Shifting animation for the screen transition where the screens slightly shift to left/right.
+
+Example:
+
+
+
+
+```js
+import { SceneStyleInterpolators } from '@react-navigation/bottom-tabs';
+
+// ...
+
+{
+ Profile: {
+ screen: Profile,
+ options: {
+ // highlight-start
+ sceneStyleInterpolator: SceneStyleInterpolators.forFade,
+ // highlight-end
+ },
+ },
+}
+```
+
+
+
+
+```js
+import { SceneStyleInterpolators } from '@react-navigation/bottom-tabs';
+
+// ...
+
+ ;
+```
+
+
+
+
+#### `TransitionPresets`
+
+We export transition presets that bundle various sets of these options together. A transition preset is an object containing a few animation-related screen options exported under `TransitionPresets`. Currently the following presets are available:
+
+- `FadeTransition` - Cross-fade animation for the screen transition where the new screen fades in and the old screen fades out.
+- `ShiftTransition` - Shifting animation for the screen transition where the screens slightly shift to left/right.
+
+You can spread these presets in `options` to customize the animation for a screen:
+
+Example:
+
+
+
+
+```js
+import { TransitionPresets } from '@react-navigation/bottom-tabs';
+
+// ...
+
+{
+ Profile: {
+ screen: Profile,
+ options: {
+ // highlight-start
+ ...TransitionPresets.FadeTransition,
+ // highlight-end
+ },
+ },
+}
+```
+
+
+
+
+```js
+import { TransitionPresets } from '@react-navigation/bottom-tabs';
+
+// ...
+
+ ;
+```
+
+
+
diff --git a/versioned_docs/version-7.x/static-combine-with-dynamic.md b/versioned_docs/version-7.x/combine-static-with-dynamic.md
similarity index 60%
rename from versioned_docs/version-7.x/static-combine-with-dynamic.md
rename to versioned_docs/version-7.x/combine-static-with-dynamic.md
index d8a65aed213..bfb8c80b619 100644
--- a/versioned_docs/version-7.x/static-combine-with-dynamic.md
+++ b/versioned_docs/version-7.x/combine-static-with-dynamic.md
@@ -1,7 +1,7 @@
---
-id: static-combine-with-dynamic
+id: combine-static-with-dynamic
title: Combining static and dynamic APIs
-sidebar_label: Combining with dynamic API
+sidebar_label: Static and dynamic APIs
---
While the static API has many advantages, it doesn't fit use cases where the navigation configuration needs to be dynamic. So React Navigation supports interop between the static and dynamic APIs.
@@ -75,10 +75,12 @@ const RootStack = createNativeStackNavigator({
screen: FeedScreen,
linking: {
path: 'feed',
+ // highlight-start
screens: {
Latest: 'latest',
Popular: 'popular',
},
+ // highlight-end
},
},
},
@@ -100,8 +102,10 @@ type FeedParamList = {
Popular: undefined;
};
+// highlight-next-line
type Props = StaticScreenProps>;
+// highlight-next-line
function FeedScreen(_: Props) {
// ...
}
@@ -119,4 +123,93 @@ This is based on how we'd define the type for a screen with a nested navigator w
This is useful if you already have a dynamic configuration, but want to migrate to the static API. This way you can migrate one navigator at a time.
-TODO
+Let's consider the following example:
+
+- You have a root stack navigator that contains a tab navigator in a screen.
+- The root stack navigator is defined using the dynamic API.
+
+Our dynamic configuration would look like this:
+
+```js
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const RootStack = createNativeStackNavigator();
+
+function RootStackScreen() {
+ return (
+
+
+
+
+ );
+}
+```
+
+Here, `FeedScreen` is a component that renders a tab navigator and is defined using the static API:
+
+```js
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+const FeedTabs = createBottomTabNavigator({
+ screens: {
+ Latest: {
+ screen: LatestScreen,
+ },
+ Popular: {
+ screen: PopularScreen,
+ },
+ },
+});
+```
+
+To use the `FeedTabs` navigator for the `Feed` screen, we need to use the `createComponentForStaticNavigation` function:
+
+```js
+import { createComponentForStaticNavigation } from '@react-navigation/native';
+
+// highlight-next-line
+const FeedScreen = createComponentForStaticNavigation(FeedTabs, 'Feed');
+```
+
+In addition, we can generate the TypeScript types for the `FeedTabs` navigator and use it in the types of `RootStack` without needing to write them manually:
+
+```tsx
+import {
+ StaticParamList,
+ NavigatorScreenParams,
+} from '@react-navigation/native';
+
+// highlight-next-line
+type FeedTabsParamList = StaticParamList;
+
+type RootStackParamList = {
+ Home: undefined;
+ // highlight-next-line
+ Feed: NavigatorScreenParams;
+};
+```
+
+Similarly, we can generate the linking configuration for the `FeedTabs` navigator and use it in the linking configuration passed to `NavigationContainer`:
+
+```js
+import { createPathConfigForStaticNavigation } from '@react-navigation/native';
+
+// highlight-next-line
+const feedScreens = createPathConfigForStaticNavigation(FeedTabs);
+
+const linking = {
+ prefixes: ['https://example.com', 'example://'],
+ config: {
+ screens: {
+ Home: '',
+ Feed: {
+ path: 'feed',
+ // highlight-next-line
+ screens: feedScreens,
+ },
+ },
+ },
+};
+```
+
+This will generate the linking configuration for the `Feed` screen based on the configuration of the `FeedTabs` navigator.
diff --git a/versioned_docs/version-7.x/community-libraries.md b/versioned_docs/version-7.x/community-libraries.md
new file mode 100755
index 00000000000..74b8fc2e3e0
--- /dev/null
+++ b/versioned_docs/version-7.x/community-libraries.md
@@ -0,0 +1,31 @@
+---
+id: community-libraries
+title: Community libraries
+sidebar_label: Community libraries
+---
+
+This guide lists various community libraries that can be used alongside React Navigation to enhance its functionality.
+
+:::note
+
+Please refer to the library's documentation to see which version of React Navigation it supports.
+
+:::
+
+## react-native-screen-transitions
+
+A library that provides customizable screen transition animations for React Navigation's [Native Stack Navigator](native-stack-navigator.md).
+
+[Repository](https://github.com/eds2002/react-native-screen-transitions)
+
+### react-navigation-header-buttons
+
+Helps you to render buttons in the navigation bar and handle the styling so you don't have to. It tries to mimic the appearance of native navbar buttons and attempts to offer a simple interface for you to interact with.
+
+[Repository](https://github.com/vonovak/react-navigation-header-buttons)
+
+### react-navigation-props-mapper
+
+Provides simple HOCs that map react-navigation props to your screen components directly - ie. instead of `const user = this.props.route.params.activeUser`, you'd write `const user = this.props.activeUser`.
+
+[Repository](https://github.com/vonovak/react-navigation-props-mapper)
diff --git a/versioned_docs/version-7.x/community-navigators.md b/versioned_docs/version-7.x/community-navigators.md
new file mode 100755
index 00000000000..74c1a3278c8
--- /dev/null
+++ b/versioned_docs/version-7.x/community-navigators.md
@@ -0,0 +1,31 @@
+---
+id: community-navigators
+title: Community navigators
+sidebar_label: Community navigators
+---
+
+This guide lists various community navigators for React Navigation. These navigators offer provide UI components for navigation with the familiar React Navigation API.
+
+If you're looking to build your own navigator, check out the [custom navigators guide](custom-navigators.md).
+
+:::note
+
+Please refer to the library's documentation to see which version of React Navigation it supports.
+
+:::
+
+## React Native Bottom Tabs
+
+This project aims to expose the native Bottom Tabs component to React Native. It exposes SwiftUI's TabView on iOS and the material design tab bar on Android. Using `react-native-bottom-tabs` can bring several benefits, including multi-platform support and a native-feeling tab bar.
+
+[Documentation](https://oss.callstack.com/react-native-bottom-tabs/)
+
+[Repository](https://github.com/callstackincubator/react-native-bottom-tabs)
+
+## BottomNavigation - React Native Paper
+
+The library provides React Navigation integration for its Material Bottom Tabs. Material Bottom Tabs is a material-design themed tab bar on the bottom of the screen that lets you switch between different routes with animation.
+
+[Documentation](https://callstack.github.io/react-native-paper/docs/guides/bottom-navigation/)
+
+[Repository](https://github.com/callstack/react-native-paper)
diff --git a/versioned_docs/version-7.x/community-solutions.md b/versioned_docs/version-7.x/community-solutions.md
new file mode 100755
index 00000000000..18b8f2c81c6
--- /dev/null
+++ b/versioned_docs/version-7.x/community-solutions.md
@@ -0,0 +1,35 @@
+---
+id: community-solutions
+title: Community solutions
+sidebar_label: Community solutions
+---
+
+This guide lists various community navigation solutions built on top of React Navigation that offer a different API or complement React Navigation in some way.
+
+:::note
+
+Please refer to the library's documentation to see which version of React Navigation it supports.
+
+:::
+
+## Expo Router
+
+Expo Router is a file-based router for React Native and web applications built by the Expo team.
+
+[Documentation](https://docs.expo.dev/router/introduction/)
+
+[Repository](https://github.com/expo/expo/tree/main/packages/expo-router)
+
+## Solito
+
+A wrapper around React Navigation and Next.js that lets you share navigation code across platforms. Also, it provides a set of patterns and examples for building cross-platform apps with React Native + Next.js.
+
+[Documentation](https://solito.dev/)
+
+[Repository](https://github.com/nandorojo/solito)
+
+## Navio
+
+Navio provides a different API for React Navigation. It's main goal is to improve DX by building the app layout in one place and using the power of TypeScript to provide route names autocompletion.
+
+[Repository](https://github.com/kanzitelli/rn-navio)
diff --git a/versioned_docs/version-7.x/configuring-links.md b/versioned_docs/version-7.x/configuring-links.md
index 43553d80e67..7b98cbee23c 100644
--- a/versioned_docs/version-7.x/configuring-links.md
+++ b/versioned_docs/version-7.x/configuring-links.md
@@ -4,6 +4,9 @@ title: Configuring links
sidebar_label: Configuring links
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
In this guide, we will configure React Navigation to handle external links. This is necessary if you want to:
1. Handle deep links in React Native apps on Android and iOS
@@ -12,11 +15,45 @@ In this guide, we will configure React Navigation to handle external links. This
Make sure that you have [configured deep links](deep-linking.md) in your app before proceeding. If you have an Android or iOS app, remember to specify the [`prefixes`](navigation-container.md#linkingprefixes) option.
+
+
+
+The [`Navigation`](static-configuration.md#createstaticnavigation) component accepts a [`linking`](static-configuration.md#differences-in-the-linking-prop) prop that makes it easier to handle incoming links:
+
+```js
+import { createStaticNavigation } from '@react-navigation/native';
+
+// highlight-start
+const linking = {
+ enabled: 'auto' /* Automatically generate paths for all screens */,
+ prefixes: [
+ /* your linking prefixes */
+ ],
+};
+// highlight-end
+
+function App() {
+ return (
+ Loading...}
+ />
+ );
+}
+
+const Navigation = createStaticNavigation(RootStack);
+```
+
+
+
+
The `NavigationContainer` accepts a [`linking`](navigation-container.md#linking) prop that makes it easier to handle incoming links. The 2 of the most important properties you can specify in the `linking` prop are `prefixes` and `config`:
```js
import { NavigationContainer } from '@react-navigation/native';
+// highlight-start
const linking = {
prefixes: [
/* your linking prefixes */
@@ -25,16 +62,24 @@ const linking = {
/* configuration for matching screens with paths */
},
};
+// highlight-end
function App() {
return (
- Loading...}>
+ Loading...}
+ >
{/* content */}
);
}
```
+
+
+
When you specify the `linking` prop, React Navigation will handle incoming links automatically. On Android and iOS, it'll use React Native's [`Linking` module](https://reactnative.dev/docs/linking) to handle incoming links, both when the app was opened with the link, and when new links are received when the app is open. On the Web, it'll use the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to sync the URL with the browser.
:::warning
@@ -43,17 +88,17 @@ Currently there seems to be bug ([facebook/react-native#25675](https://github.co
:::
-You can also pass a [`fallback`](navigation-container.md#fallback) prop to `NavigationContainer` which controls what's displayed when React Navigation is trying to resolve the initial deep link URL.
+You can also pass a [`fallback`](navigation-container.md#fallback) prop that controls what's displayed when React Navigation is trying to resolve the initial deep link URL.
## Prefixes
-The `prefixes` option can be used to specify custom schemes (e.g. `mychat://`) as well as host & domain names (e.g. `https://mychat.com`) if you have configured [Universal Links](https://developer.apple.com/ios/universal-links/) or [Android App Links](https://developer.android.com/training/app-links).
+The `prefixes` option can be used to specify custom schemes (e.g. `example://`) as well as host & domain names (e.g. `https://example.com`) if you have configured [Universal Links](https://developer.apple.com/ios/universal-links/) or [Android App Links](https://developer.android.com/training/app-links).
For example:
```js
const linking = {
- prefixes: ['mychat://', 'https://mychat.com'],
+ prefixes: ['example://', 'https://example.com'],
};
```
@@ -61,54 +106,194 @@ Note that the `prefixes` option is not supported on Web. The host & domain names
### Multiple subdomains
-To match all subdomains of an associated domain, you can specify a wildcard by prefixing `*`. before the beginning of a specific domain. Note that an entry for `*.mychat.com` does not match `mychat.com` because of the period after the asterisk. To enable matching for both `*.mychat.com` and `mychat.com`, you need to provide a separate prefix entry for each.
+To match all subdomains of an associated domain, you can specify a wildcard by prefixing `*`. before the beginning of a specific domain. Note that an entry for `*.example.com` does not match `example.com` because of the period after the asterisk. To enable matching for both `*.example.com` and `example.com`, you need to provide a separate prefix entry for each.
```js
const linking = {
- prefixes: ['mychat://', 'https://mychat.com', 'https://*.mychat.com'],
+ prefixes: ['example://', 'https://example.com', 'https://*.example.com'],
};
```
+## Filtering certain paths
+
+Sometimes we may not want to handle all incoming links. For example, we may want to filter out links meant for authentication (e.g. `expo-auth-session`) or other purposes instead of navigating to a specific screen.
+
+To achieve this, you can use the `filter` option:
+
+```js
+const linking = {
+ prefixes: ['example://', 'https://example.com'],
+ // highlight-next-line
+ filter: (url) => !url.includes('+expo-auth-session'),
+};
+```
+
+This is not supported on Web as we always need to handle the URL of the page.
+
+## Apps under subpaths
+
+If your app is hosted under a subpath, you can specify the subpath at the top-level of the `config`. For example, if your app is hosted at `https://example.com/app`, you can specify the `path` as `app`:
+
+```js
+const linking = {
+ prefixes: ['example://', 'https://example.com'],
+ config: {
+ // highlight-next-line
+ path: 'app',
+
+ // ...
+ },
+};
+```
+
+It's not possible to specify params here since this doesn't belong to a screen, e.g. `app/:id` won't work.
+
## Mapping path to route names
-To handle a link, you need to translate it to a valid [navigation state](navigation-state.md) and vice versa. For example, the path `/rooms/chat?user=jane` may be translated to a state object like this:
+
+
+
+If you specify `enabled: 'auto'` in the `linking` prop, React Navigation will automatically generate paths for all screens. For example, if you have a `Profile` screen in the navigator, it'll automatically generate a path for it as `profile`.
+
+If you wish to handle the configuration manually, or want to override the generated path for a specific screen, you can specify `linking` property next to the screen in the navigator to map a path to a screen. For example:
```js
-const state = {
- routes: [
- {
- name: 'rooms',
- state: {
- routes: [
- {
- name: 'chat',
- params: { user: 'jane' },
- },
- ],
+const RootStack = createStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-start
+ linking: {
+ path: 'user',
},
+ // highlight-end
},
- ],
-};
+ Chat: {
+ screen: ChatScreen,
+ // highlight-start
+ linking: {
+ path: 'feed/:sort',
+ },
+ // highlight-end
+ },
+ },
+});
```
-By default, React Navigation will use the path segments as the route name when parsing the URL. But directly translating path segments to route names may not be the expected behavior.
+In this example:
-For example, you might want to parse the path `/feed/latest` to something like:
+- `Chat` screen that handles the URL `/feed` with the param `sort` (e.g. `/feed/latest` - the `Chat` screen will receive a param `sort` with the value `latest`).
+- `Profile` screen that handles the URL `/user`.
+
+Similarly, when you have a nested navigator, you can specify the `linking` property for the screens in the navigator to handle the path for the nested screens:
```js
-const state = {
- routes: [
- {
- name: 'Chat',
- params: {
- sort: 'latest',
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ // highlight-start
+ linking: {
+ path: 'home',
},
+ // highlight-end
},
- ];
-}
+ Settings: {
+ screen: SettingsScreen,
+ // highlight-start
+ linking: {
+ path: 'settings',
+ },
+ // highlight-end
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ screens: {
+ HomeTabs: {
+ screen: HomeTabs,
+ },
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-start
+ linking: {
+ path: 'user',
+ },
+ // highlight-end
+ },
+ Chat: {
+ screen: ChatScreen,
+ // highlight-start
+ linking: {
+ path: 'feed/:sort',
+ },
+ // highlight-end
+ },
+ },
+});
```
-You can specify the [`config`](navigation-container.md#linkingconfig) option in `linking` to control how the deep link is parsed to suit your needs.
+In the above example, the following path formats are handled:
+
+- `/home` navigates to the `HomeTabs` -> `Home` screen
+- `/settings` navigates to the `HomeTabs` -> `Settings` screen
+- `/user` navigates to the `Profile` screen
+- `/feed/:sort` navigates to the `Chat` screen with the param `sort`
+
+### How does automatic path generation work?
+
+When using automatic path generation with `enabled: 'auto'`, the following rules are applied:
+
+- Screens with an explicit `linking` property are not used for path generation and will be added as-is.
+- Screen names will be converted from `PascalCase` to `kebab-case` to use as the path (e.g. `NewsFeed` -> `news-feed`).
+- Unless a screen has explicit empty path (`path: ''`) to use for the homepage, the first leaf screen encountered will be used as the homepage.
+- Path generation only handles leaf screens, i.e. no path is generated for screens containing nested navigators. It's still possible to specify a path for them with an explicit `linking` property.
+
+Let's say we have the following navigation structure:
+
+```js
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ },
+ Settings: {
+ screen: SettingsScreen,
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ screens: {
+ HomeTabs: {
+ screen: HomeTabs,
+ },
+ Profile: {
+ screen: ProfileScreen,
+ },
+ Chat: {
+ screen: ChatScreen,
+ },
+ },
+});
+```
+
+With automatic path generation, the following paths will be generated:
+
+- `/` navigates to the `HomeTabs` -> `Home` screen
+- `/settings` navigates to the `HomeTabs` -> `Settings` screen
+- `/profile` navigates to the `Profile` screen
+- `/chat` navigates to the `Chat` screen
+
+If the URL contains a query string, it'll be passed as params to the screen. For example, the URL `/profile?user=jane` will pass the `user` param to the `Profile` screen.
+
+
+
+
+If you specify a `linking` option, by default React Navigation will use the path segments as the route name when parsing the URL. However, directly translating path segments to route names may not be the expected behavior.
+
+You can specify the [`config`](navigation-container.md#linkingconfig) option in `linking` to control how the deep link is parsed to suit your needs. The config should specify the mapping between route names and path patterns:
```js
const config = {
@@ -119,7 +304,10 @@ const config = {
};
```
-Here `Chat` is the name of the screen that handles the URL `/feed`, and `Profile` handles the URL `/user`.
+In this example:
+
+- `Chat` screen that handles the URL `/feed` with the param `sort` (e.g. `/feed/latest` - the `Chat` screen will receive a param `sort` with the value `latest`).
+- `Profile` screen that handles the URL `/user`.
The config option can then be passed in the `linking` prop to the container:
@@ -134,7 +322,7 @@ const config = {
};
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config,
};
@@ -181,7 +369,7 @@ function HomeScreen() {
}
```
-For above structure, our configuration will look like this:
+For the above structure, our configuration will look like this:
```js
const config = {
@@ -196,59 +384,167 @@ const config = {
};
```
-Similarly, any nesting needs to be reflected in the configuration. See [handling nested navigators](#handling-nested-navigators) for more details.
+Similarly, any nesting needs to be reflected in the configuration.
+
+
+
+
+How it works
+
+The linking works by translating the URL to a valid [navigation state](navigation-state.md) and vice versa using the configuration provided. For example, the path `/rooms/chat?user=jane` may be translated to a state object like this:
+
+```js
+const state = {
+ routes: [
+ {
+ name: 'rooms',
+ state: {
+ routes: [
+ {
+ name: 'chat',
+ params: { user: 'jane' },
+ },
+ ],
+ },
+ },
+ ],
+};
+```
+
+For example, you might want to parse the path `/feed/latest` to something like:
+
+```js
+const state = {
+ routes: [
+ {
+ name: 'Chat',
+ params: {
+ sort: 'latest',
+ },
+ },
+ ];
+}
+```
+
+See [Navigation State reference](navigation-state.md) for more details on how the state object is structured.
+
+
## Passing params
A common use case is to pass params to a screen to pass some data. For example, you may want the `Profile` screen to have an `id` param to know which user's profile it is. It's possible to pass params to a screen through a URL when handling deep links.
-By default, query params are parsed to get the params for a screen. For example, with the above example, the URL `/user?id=wojciech` will pass the `id` param to the `Profile` screen.
+By default, query params are parsed to get the params for a screen. For example, with the above example, the URL `/user?id=jane` will pass the `id` param to the `Profile` screen.
-You can also customize how the params are parsed from the URL. Let's say you want the URL to look like `/user/wojciech` where the `id` param is `wojciech` instead of having the `id` in query params. You can do this by specifying `user/:id` for the `path`. **When the path segment starts with `:`, it'll be treated as a param**. For example, the URL `/user/wojciech` would resolve to `Profile` screen with the string `wojciech` as a value of the `id` param and will be available in `route.params.id` in `Profile` screen.
+You can also customize how the params are parsed from the URL. Let's say you want the URL to look like `/user/jane` where the `id` param is `jane` instead of having the `id` in query params. You can do this by specifying `user/:id` for the `path`. **When the path segment starts with `:`, it'll be treated as a param**. For example, the URL `/user/jane` would resolve to `Profile` screen with the string `jane` as a value of the `id` param and will be available in `route.params.id` in `Profile` screen.
By default, all params are treated as strings. You can also customize how to parse them by specifying a function in the `parse` property to parse the param, and a function in the `stringify` property to convert it back to a string.
-If you wanted to resolve `/user/wojciech/settings` to result in the params `{ id: 'user-wojciech' section: 'settings' }`, you could make `Profile`'s config to look like this:
+If you wanted to resolve `/user/@jane/settings` to result in the params `{ id: 'jane' section: 'settings' }`, you could make `Profile`'s config to look like this:
+
+
+
+
+```js
+const RootStack = createStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-start
+ linking: {
+ path: 'user/:id/:section',
+ parse: {
+ id: (id) => id.replace(/^@/, ''),
+ },
+ stringify: {
+ id: (id) => `@${id}`,
+ },
+ },
+ // highlight-end
+ },
+ },
+});
+```
+
+
+
```js
const config = {
screens: {
Profile: {
+ // highlight-start
path: 'user/:id/:section',
parse: {
- id: (id) => `user-${id}`,
+ id: (id) => id.replace(/^@/, ''),
},
stringify: {
- id: (id) => id.replace(/^user-/, ''),
+ id: (id) => `@${id}`,
},
+ // highlight-end
},
},
};
```
-This will result in something like:
+
+
+
+
+Result Navigation State
+
+With this configuration, the path `/user/@jane/settings` will resolve to the following state object:
```js
const state = {
routes: [
{
name: 'Profile',
- params: { id: 'user-wojciech', section: 'settings' },
+ params: { id: 'jane', section: 'settings' },
},
],
};
```
+
+
## Marking params as optional
-Sometimes a param may or may not be present in the URL depending on certain conditions. For example, in the above scenario, you may not always have the section parameter in the URL, i.e. both `/user/wojciech/settings` and `/user/wojciech` should go to the `Profile` screen, but the `section` param (with the value `settings` in this case) may or may not be present.
+Sometimes a param may or may not be present in the URL depending on certain conditions. For example, in the above scenario, you may not always have the section parameter in the URL, i.e. both `/user/jane/settings` and `/user/jane` should go to the `Profile` screen, but the `section` param (with the value `settings` in this case) may or may not be present.
In this case, you would need to mark the `section` param as optional. You can do it by adding the `?` suffix after the param name:
+
+
+
+```js
+const RootStack = createStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ linking: {
+ // highlight-next-line
+ path: 'user/:id/:section?',
+ parse: {
+ id: (id) => `user-${id}`,
+ },
+ stringify: {
+ id: (id) => id.replace(/^user-/, ''),
+ },
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
const config = {
screens: {
Profile: {
+ // highlight-next-line
path: 'user/:id/:section?',
parse: {
id: (id) => `user-${id}`,
@@ -261,99 +557,88 @@ const config = {
};
```
-With the URL `/users/wojciech`, this will result in:
+
+
+
+
+Result Navigation State
+
+With this configuration, the path `/user/jane` will resolve to the following state object:
```js
const state = {
routes: [
{
name: 'Profile',
- params: { id: 'user-wojciech' },
+ params: { id: 'user-jane' },
},
],
};
```
-If the URL contains a `section` param, e.g. `/users/wojciech/settings`, this will result in the following with the same config:
+If the URL contains a `section` param (e.g. `/user/jane/settings`), this will result in the following with the same config:
```js
const state = {
routes: [
{
name: 'Profile',
- params: { id: 'user-wojciech', section: 'settings' },
+ params: { id: 'user-jane', section: 'settings' },
},
],
};
```
-## Handling nested navigators
+
-Sometimes you'll have the target navigator nested in other navigators which aren't part of the deep link. For example, let's say your navigation structure looks like this:
+## Handling unmatched routes or 404
-```js
-function Home() {
- return (
-
-
-
-
- );
-}
+If your app is opened with an invalid URL, most of the times you'd want to show an error page with some information. On the web, this is commonly known as 404 - or page not found error.
-function App() {
- return (
-
-
-
-
- );
-}
-```
+To handle this, you'll need to define a catch-all route that will be rendered if no other routes match the path. You can do it by specifying `*` for the path matching pattern:
-Here you have a stack navigator in the root, and inside the `Home` screen of the root stack, you have a tab navigator with various screens. With this structure, let's say you want the path `/users/:id` to go to the `Profile` screen. You can express the nested config like so:
+
+
```js
-const config = {
+const HomeTabs = createBottomTabNavigator({
screens: {
- Home: {
- screens: {
- Profile: 'users/:id',
+ Feed: {
+ screen: FeedScreen,
+ },
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ },
+ },
+ Settings: {
+ screen: SettingsScreen,
+ linking: {
+ path: 'settings',
},
},
},
-};
-```
-
-In this config, you specify that the `Profile` screen should be resolved for the `users/:id` pattern and it's nested inside the `Home` screen. Then parsing `users/jane` will result in the following state object:
+});
-```js
-const state = {
- routes: [
- {
- name: 'Home',
- state: {
- routes: [
- {
- name: 'Profile',
- params: { id: 'jane' },
- },
- ],
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeTabs,
+ },
+ NotFound: {
+ screen: NotFoundScreen,
+ linking: {
+ // highlight-next-line
+ path: '*',
},
},
- ],
-};
+ },
+});
```
-It's important to note that the state object must match the hierarchy of nested navigators. Otherwise the state will be discarded.
-
-## Handling unmatched routes or 404
-
-If your app is opened with an invalid URL, most of the times you'd want to show an error page with some information. On the web, this is commonly known as 404 - or page not found error.
-
-To handle this, you'll need to define a catch-all route that will be rendered if no other routes match the path. You can do it by specifying `*` for the path matching pattern.
-
-For example:
+
+
```js
const config = {
@@ -365,14 +650,23 @@ const config = {
Settings: 'settings',
},
},
- NotFound: '*',
+ NotFound: {
+ // highlight-start
+ path: '*',
+ },
},
};
```
+
+
+
Here, we have defined a route named `NotFound` and set it to match `*` aka everything. If the path didn't match `user/:id` or `settings`, it'll be matched by this route.
-So, a path like `/library` or `/settings/notification` will resolve to the following state object:
+
+Result Navigation State
+
+With this configuration, a path like `/library` or `/settings/notification` will resolve to the following state object:
```js
const state = {
@@ -380,8 +674,67 @@ const state = {
};
```
+
+
You can even go more specific, for example, say if you want to show a different screen for invalid paths under `/settings`, you can specify such a pattern under `Settings`:
+
+
+
+```js
+const SettingsStack = createStackNavigator({
+ screens: {
+ UserSettings: {
+ screen: UserSettingsScreen,
+ linking: {
+ path: 'user-settings',
+ },
+ },
+ InvalidSettings: {
+ screen: InvalidSettingsScreen,
+ linking: {
+ // highlight-next-line
+ path: '*',
+ },
+ },
+ },
+});
+
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Feed: {
+ screen: FeedScreen,
+ },
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ },
+ },
+ Settings: {
+ screen: SettingsStack,
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeTabs,
+ },
+ NotFound: {
+ screen: NotFoundScreen,
+ linking: {
+ path: '*',
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
const config = {
screens: {
@@ -402,6 +755,12 @@ const config = {
};
```
+
+
+
+
+Result Navigation State
+
With this configuration, the path `/settings/notification` will resolve to the following state object:
```js
@@ -428,6 +787,8 @@ const state = {
};
```
+
+
The `route` passed to the `NotFound` screen will contain a `path` property which corresponds to the path that opened the page. If you need, you can use this property to customize what's shown in this screen, e.g. load the page in a `WebView`:
```js
@@ -448,10 +809,57 @@ Sometimes you want to ensure that a certain screen will always be present as the
In the above example, if you want the `Feed` screen to be the initial route in the navigator under `Home`, your config will look like this:
+
+
+
+```js
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Feed: {
+ screen: FeedScreen,
+ },
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ },
+ },
+ Settings: {
+ screen: SettingsScreen,
+ linking: {
+ path: 'settings',
+ },
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeTabs,
+ linking: {
+ // highlight-next-line
+ initialRouteName: 'Feed',
+ },
+ },
+ NotFound: {
+ screen: NotFoundScreen,
+ linking: {
+ path: '*',
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
const config = {
screens: {
Home: {
+ // highlight-next-line
initialRouteName: 'Feed',
screens: {
Profile: 'users/:id',
@@ -462,7 +870,13 @@ const config = {
};
```
-Then, the path `/users/42` will resolve to the following state object:
+
+
+
+
+Result Navigation State
+
+With this configuration, the path `/users/42` will resolve to the following state object:
```js
const state = {
@@ -484,6 +898,8 @@ const state = {
};
```
+
+
:::warning
The `initialRouteName` will add the screen to React Navigation's state only. If your app is running on the Web, the browser's history will not contain this screen as the user has never visited it. So, if the user presses the browser's back button, it'll not go back to this screen.
@@ -494,12 +910,42 @@ Another thing to keep in mind is that it's not possible to pass params to the in
In this case, any params in the URL are only passed to the `Profile` screen which matches the path pattern `users/:id`, and the `Feed` screen doesn't receive any params. If you want to have the same params in the `Feed` screen, you can specify a [custom `getStateFromPath` function](navigation-container.md#linkinggetstatefrompath) and copy those params.
-Similarly, if you want to access params of a parent screen from a child screen, you can use [React Context](https://reactjs.org/docs/context.html) to expose them.
+Similarly, if you want to access params of a parent screen from a child screen, you can use [React Context](https://react.dev/reference/react/useContext) to expose them.
## Matching exact paths
By default, paths defined for each screen are matched against the URL relative to their parent screen's path. Consider the following config:
+
+
+
+```js
+const ProfileTabs = createBottomTabNavigator({
+ screens: {
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ },
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: ProfileTabs,
+ linking: {
+ path: 'feed',
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
const config = {
screens: {
@@ -513,12 +959,47 @@ const config = {
};
```
+
+
+
Here, you have a `path` property defined for the `Home` screen, as well as the child `Profile` screen. The profile screen specifies the path `users/:id`, but since it's nested inside a screen with the path `feed`, it'll try to match the pattern `feed/users/:id`.
This will result in the URL `/feed` navigating to `Home` screen, and `/feed/users/cal` navigating to the `Profile` screen.
In this case, it makes more sense to navigate to the `Profile` screen using a URL like `/users/cal`, rather than `/feed/users/cal`. To achieve this, you can override the relative matching behavior to `exact` matching:
+
+
+
+```js
+const ProfileTabs = createBottomTabNavigator({
+ screens: {
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ // highlight-next-line
+ exact: true,
+ },
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: ProfileTabs,
+ linking: {
+ path: 'feed',
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
const config = {
screens: {
@@ -527,6 +1008,7 @@ const config = {
screens: {
Profile: {
path: 'users/:id',
+ // highlight-next-line
exact: true,
},
},
@@ -535,66 +1017,121 @@ const config = {
};
```
+
+
+
With `exact` property set to `true`, `Profile` will ignore the parent screen's `path` config and you'll be able to navigate to `Profile` using a URL like `users/cal`.
## Omitting a screen from path
-Sometimes, you may not want to have the route name of a screen in the path. For example, let's say you have a `Home` screen and our [navigation state](navigation-state.md) looks like this:
+Sometimes, you may not want to have the route name of a screen in the path. For example, let's say you have a `Home` screen and the following config. When the page is opened in the browser you'll get `/home` as the URL:
+
+
+
```js
-const state = {
- routes: [{ name: 'Home' }],
-};
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: ProfileScreen,
+ linking: {
+ path: 'home',
+ },
+ },
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ },
+ },
+ },
+});
```
-When this state is serialized to a path with the following config, you'll get `/home`:
+
+
```js
const config = {
screens: {
Home: {
path: 'home',
- screens: {
- Profile: 'users/:id',
- },
},
+ Profile: 'users/:id',
},
};
```
-But it'll be nicer if the URL was just `/` when visiting the home screen. You can specify an empty string as path or not specify a path at all, and React Navigation won't add the screen to the path (think of it like adding empty string to the path, which doesn't change anything):
+
+
+
+But it'll be nicer if the URL was just `/` when visiting the home screen.
+
+You can specify an empty string as path or not specify a path at all, and React Navigation won't add the screen to the path (think of it like adding empty string to the path, which doesn't change anything):
+
+
+
+
+```js
+const RootStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: ProfileScreen,
+ linking: {
+ path: '',
+ },
+ },
+ Profile: {
+ screen: HomeScreen,
+ linking: {
+ path: 'users/:id',
+ },
+ },
+ },
+});
+```
+
+
+
```js
const config = {
screens: {
Home: {
path: '',
- screens: {
- Profile: 'users/:id',
- },
},
+ Profile: 'users/:id',
},
};
```
+
+
+
## Serializing and parsing params
Since URLs are strings, any params you have for routes are also converted to strings when constructing the path.
-For example, say you have a state like following:
+For example, say you have the URL `/chat/1589842744264` with the following config:
+
+
+
```js
-const state = {
- routes: [
- {
- name: 'Chat',
- params: { at: 1589842744264 },
+const RootStack = createStackNavigator({
+ screens: {
+ Chat: {
+ screen: ChatScreen,
+ linking: {
+ path: 'chat/:date',
+ },
},
- ];
-}
+ },
+});
```
-It'll be converted to `chat/1589842744264` with the following config:
+
+
```js
const config = {
@@ -604,20 +1141,38 @@ const config = {
};
```
-When parsing this path, you'll get the following state:
+
+
+
+When handling the URL, your params will look like this:
+
+```yml
+{ date: '1589842744264' }
+```
+
+Here, the `date` param was parsed as a string because React Navigation doesn't know that it's supposed to be a timestamp, and hence number. You can customize it by providing a custom function to use for parsing:
+
+
+
```js
-const state = {
- routes: [
- {
- name: 'Chat',
- params: { date: '1589842744264' },
+const RootStack = createStackNavigator({
+ screens: {
+ Chat: {
+ screen: ChatScreen,
+ linking: {
+ path: 'chat/:date',
+ parse: {
+ date: Number,
+ },
+ },
},
- ];
-}
+ },
+});
```
-Here, the `date` param was parsed as a string because React Navigation doesn't know that it's supposed to be a timestamp, and hence number. You can customize it by providing a custom function to use for parsing:
+
+
```js
const config = {
@@ -632,7 +1187,39 @@ const config = {
};
```
-You can also provide a custom function to serialize the params. For example, let's say that you want to use a DD-MM-YYYY format in the path instead of a timestamp:
+
+
+
+You can also provide a your own function to serialize the params. For example, let's say that you want to use a DD-MM-YYYY format in the path instead of a timestamp:
+
+
+
+
+```js
+const RootStack = createStackNavigator({
+ screens: {
+ Chat: {
+ screen: ChatScreen,
+ linking: {
+ path: 'chat/:date',
+ parse: {
+ date: (date) => new Date(date).getTime(),
+ },
+ stringify: {
+ date: (date) => {
+ const d = new Date(date);
+
+ return d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate();
+ },
+ },
+ },
+ },
+ },
+});
+```
+
+
+
```js
const config = {
@@ -654,129 +1241,151 @@ const config = {
};
```
+
+
+
Depending on your requirements, you can use this functionality to parse and stringify more complex data.
-## Advanced cases
+## Matching regular expressions
-For some advanced cases, specifying the mapping may not be sufficient. To handle such cases, you can specify a custom function to parse the URL into a state object ([`getStateFromPath`](navigation-container.md#linkinggetstatefrompath)), and a custom function to serialize the state object into an URL ([`getPathFromState`](navigation-container.md#linkinggetpathfromstate)).
+If you need more complex matching logic, you can use regular expressions to match the path. For example, if you want to use the pattern `@username` to match a user's profile, you can use a regular expression to match the path. This allows you to have the same path pattern for multiple screens, but fine-tune the matching logic to be more specific for a particular screen.
-Example:
+Regular expressions can be specified between parentheses `(` and `)` in the after a param name. For example:
+
+
+
```js
-const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
- config: {
- screens: {
- Chat: 'feed/:sort',
+const RootStack = createStackNavigator({
+ screens: {
+ Feed: {
+ screen: FeedScreen,
+ linking: {
+ path: ':sort(latest|popular)',
+ },
+ },
+ Profile: {
+ screen: ProfileScreen,
+ linking: {
+ path: ':username(@[A-Za-z0-9_]+)',
+ },
},
},
- getStateFromPath: (path, options) => {
- // Return a state object here
- // You can also reuse the default logic by importing `getStateFromPath` from `@react-navigation/native`
- },
- getPathFromState(state, config) {
- // Return a path string here
- // You can also reuse the default logic by importing `getPathFromState` from `@react-navigation/native`
- },
-};
-```
-
-## Updating config
-
-Older versions of React Navigation had a slightly different configuration format for linking. The old config allowed a simple key value pair in the object regardless of nesting of navigators:
-
-```js
-const config = {
- Home: 'home',
- Feed: 'feed',
- Profile: 'profile',
- Settings: 'settings',
-};
+});
```
-Let's say, your `Feed` and `Profile` screens are nested inside `Home`. Even if you don't have such a nesting with the above configuration, as long as the URL was `/home/profile`, it would work. Furthermore, it would also treat path segments and route names the same, which means that you could deep link to a screen that's not specified in the configuration. For example, if you have a `Albums` screen inside `Home`, the deep link `/home/Albums` would navigate to that screen. While that may be desirable in some cases, there's no way to prevent access to specific screens. This approach also makes it impossible to have something like a 404 screen since any route name is a valid path.
-
-Latest versions of React Navigation use a different config format which is stricter in this regard:
-
-- The shape of the config must match the shape of the nesting in the navigation structure
-- Only screens defined in the config will be eligible for deep linking
-
-So, you'd refactor the above config to the following format:
+
+
```js
const config = {
screens: {
- Home: {
- path: 'home',
- screens: {
- Feed: 'feed',
- Profile: 'profile',
- },
- },
- Settings: 'settings',
+ Feed: ':sort(latest|popular)',
+ Profile: ':username(@[A-Za-z0-9_]+)',
},
};
```
-Here, there's a new `screens` property to the configuration object, and the `Feed` and `Profile` configs are now nested under `Home` to match the navigation structure.
+
+
-If you have the old format, it will continue to work without any changes. However, you won't be able to specify a wildcard pattern to handle unmatched screens or prevent screens from being deep linked. The old format will be removed in the next major release. So we recommend to migrate to the new format when you can.
+This will only match the path if it starts with `@` followed by alphanumeric characters or underscores. For example, the URL `/@jane` will match the `Profile` screen, but `/jane` won't.
-## Playground
+Regular expressions are intended to only match path segments, not the entire path. So avoid using `/`, `^`, `$`, etc. in the regular expressions.
-You can play around with customizing the config and path below, and see how the path is parsed.
+:::warning
-import LinkingTester from '@site/src/components/LinkingTester'
+Regular expressions are an advanced feature. They cannot be validated to warn you about potential issues, so it's up to you to ensure that the regular expression is correct.
-
+:::
+
+## Alias for paths
-## Example App
+If you want to have multiple paths for the same screen, you can use the `alias` property to specify an array of paths. This can be useful to keep backward compatibility with old URLs while transitioning to a new URL structure.
-In the example app, you will use the Expo managed workflow. The guide will focus on creating the deep linking configuration and not on creating the components themselves, but you can always check the full implementation in the [github repo](https://github.com/react-navigation/deep-linking-example).
+For example, if you want to match both `/users/:id` and `/:id` to the `Profile` screen, you can do this:
-First, you need to decide the navigation structure of your app. To keep it simple, the main navigator will be bottom-tabs navigator with two screens. Its first screen will be a simple stack navigator, called `HomeStack`, with two screens: `Home` and `Profile`, and the second tabs screen will be just a simple one without any nested navigators, called `Settings`:
+
+
-```bash
-BottomTabs
-├── Stack (HomeStack)
-│ ├── Home
-│ └── Profile
-└── Settings
+```js
+const RootStack = createStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ linking: {
+ path: ':id',
+ alias: ['users/:id'],
+ },
+ },
+ },
+});
```
-After creating the navigation structure, you can create a config for deep linking, which will contain mappings for each screen to a path segment. For example:
+
+
```js
const config = {
screens: {
- HomeStack: {
- screens: {
- Home: 'home',
- Profile: 'user',
- },
+ Profile: {
+ path: ':id',
+ alias: ['users/:id'],
},
- Settings: 'settings',
},
};
```
-As you can see, `Home` and `Profile` are nested in the `screens` property of `HomeStack`. This means that when you pass the `/home` URL, it will be resolved to a `HomeStack`->`Home` state object (similarly for `/user` it would be `HomeStack`->`Profile`). The nesting in this object should match the nesting of our navigators.
+
+
+
+In this case, when the URL is `/users/jane` or `/jane`, it'll match the `Profile` screen. The `path` is the primary pattern that will be used to generate the URL, e.g. when navigating to the `Profile` screen in the app on the Web. The patterns in `alias` will be ignored when generating URLs. The `alias` patterns are not used for matching any child screens in nested navigators.
-Here, the `HomeStack` property contains a config object. The config can go as deep as you want, e.g. if `Home` was a navigator, you could make it an object with `screens` property, and put more screens or navigators inside it, making the URL string much more readable.
+On the web, if a screen containing an alias contains a nested navigator, the URL matching the alias will only be used to match the screen, and will be updated to the URL of the focused child screen once the app renders.
-What if you wanted a specific screen to used as the initial screen in the navigator? For example, if you had a URL that would open `Home` screen, you would like to be able to navigate to `Profile` from it by using navigation's `navigation.goBack()` method. It is possible by defining `initialRouteName` for a navigator. It would look like this:
+Each item in the `alias` array can be a string matching the syntax of the `path` property, or an object with the following properties:
+
+- `path` (required) - The path pattern to match.
+- `exact` - Whether to match the path exactly. Defaults to `false`. See [Matching exact paths](#matching-exact-paths) for more details.
+- `parse` - Function to parse path segments into param values. See [Passing params](#passing-params) for more details.
+
+## Advanced cases
+
+For some advanced cases, specifying the mapping may not be sufficient. To handle such cases, you can specify a custom function to parse the URL into a state object ([`getStateFromPath`](navigation-container.md#linkinggetstatefrompath)), and a custom function to serialize the state object into an URL ([`getPathFromState`](navigation-container.md#linkinggetpathfromstate)).
+
+Example:
```js
-const config = {
- screens: {
- HomeStack: {
- initialRouteName: 'Profile',
- screens: {
- Home: 'home',
- Profile: 'user',
- },
- },
- Settings: 'settings',
+const linking = {
+ prefixes: ['https://example.com', 'example://'],
+ getStateFromPath: (path, options) => {
+ // Return a state object here
+ // You can also reuse the default logic by importing `getStateFromPath` from `@react-navigation/native`
+ },
+ getPathFromState(state, config) {
+ // Return a path string here
+ // You can also reuse the default logic by importing `getPathFromState` from `@react-navigation/native`
},
+
+ // ...
};
```
+
+## Playground
+
+import LinkingTester from '@site/src/components/LinkingTester'
+
+
+
+
+Playground is not available for static config.
+
+
+
+
+You can play around with customizing the config and path below, and see how the path is parsed.
+
+
+
+
+
diff --git a/versioned_docs/version-7.x/contributing.md b/versioned_docs/version-7.x/contributing.md
index aa31a3cb0b6..ec05c128ca0 100755
--- a/versioned_docs/version-7.x/contributing.md
+++ b/versioned_docs/version-7.x/contributing.md
@@ -15,23 +15,9 @@ Here are some of the ways to contribute to the project:
- [Bug Fixes](#bug-fixes)
- [Suggesting a Feature](#suggesting-a-feature)
- [Big Pull Requests](#big-pull-requests)
-- [Information](#information)
- - [Issue Template](#issue-template)
- - [Pull Request Template](#pull-request-template)
- - [Forking the Repository](#forking-the-repository)
- - [Code Review Guidelines](#code-review-guidelines)
- - [Run the Example App](#run-the-example-app)
- - [Run Tests](#run-tests)
And here are a few helpful resources to aid in getting started:
-- [Contributing](#contributing)
- - [Reporting Bugs](#reporting-bugs)
- - [Improving the Documentation](#improving-the-documentation)
- - [Responding to Issues](#responding-to-issues)
- - [Bug Fixes](#bug-fixes)
- - [Suggesting a Feature](#suggesting-a-feature)
- - [Big Pull Requests](#big-pull-requests)
- [Information](#information)
- [Issue Template](#issue-template)
- [Pull Request Template](#pull-request-template)
@@ -47,7 +33,7 @@ And here are a few helpful resources to aid in getting started:
You can't write code without writing the occasional bug. Especially as React Navigation is moving quickly, bugs happen. When you think you've found one here's what to do:
1. Search the existing issues for one like what you're seeing. If you see one, add a 👍 reaction (please no +1 comments). Read through the comments and see if you can provide any more valuable information to the thread
-2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE.md).
+2. If there are no other issues like yours then create a new one. Be sure to follow the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE/bug-report.yml).
Creating a high quality reproduction is critical. Without it we likely can't fix the bug and, in an ideal situation, you'll find out that it's not actually a bug of the library but simply done incorrectly in your project. Instant bug fix!
@@ -96,7 +82,7 @@ The reason we want to do this is to save everyone time. Maybe that feature alrea
### Issue Template
-Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE.md) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
+Before submitting an issue, please take a look at the [issue template](https://github.com/react-navigation/react-navigation/blob/main/.github/ISSUE_TEMPLATE/bug-report.yml) and follow it. This is in place to help everyone better understand the issue you're having and reduce the back and forth to get the necessary information.
Yes, it takes time and effort to complete the issue template. But that's the only way to ask high quality questions that actually get responses.
@@ -104,7 +90,7 @@ Would you rather take 1 minute to create an incomplete issue report and wait mon
### Pull Request Template
-Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/main/.github/PULL_REQUEST.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
+Much like the issue template, the [pull request template](https://github.com/react-navigation/react-navigation/blob/main/.github/PULL_REQUEST_TEMPLATE.md) lays out instructions to ensure your pull request gets reviewed in a timely manner and reduces the back and forth. Make sure to look it over before you start writing any code.
### Forking the Repository
diff --git a/versioned_docs/version-7.x/custom-android-back-button-handling.md b/versioned_docs/version-7.x/custom-android-back-button-handling.md
index 78cafc54bf5..ce741a6180e 100755
--- a/versioned_docs/version-7.x/custom-android-back-button-handling.md
+++ b/versioned_docs/version-7.x/custom-android-back-button-handling.md
@@ -1,42 +1,250 @@
---
id: custom-android-back-button-handling
title: Custom Android back button behavior
-sidebar_label: Custom Android back button behavior
+sidebar_label: Android back button behavior
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
By default, when user presses the Android hardware back button, react-navigation will pop a screen or exit the app if there are no screens to pop. This is a sensible default behavior, but there are situations when you might want to implement custom handling.
As an example, consider a screen where user is selecting items in a list, and a "selection mode" is active. On a back button press, you would first want the "selection mode" to be deactivated, and the screen should be popped only on the second back button press. The following code snippet demonstrates the situation. We make use of [`BackHandler`](https://reactnative.dev/docs/backhandler.html) which comes with react-native, along with the `useFocusEffect` hook to add our custom `hardwareBackPress` listener.
Returning `true` from `onBackPress` denotes that we have handled the event, and react-navigation's listener will not get called, thus not popping the screen. Returning `false` will cause the event to bubble up and react-navigation's listener will pop the screen.
-
+
+
+
+```js name="Custom android back button" snack
+import * as React from 'react';
+import { Text, View, BackHandler, StyleSheet } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { useFocusEffect } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { PlatformPressable, Button } from '@react-navigation/elements';
+
+const listData = [{ key: 'Apple' }, { key: 'Orange' }, { key: 'Carrot' }];
-```js
+// codeblock-focus-start
function ScreenWithCustomBackBehavior() {
+ // codeblock-focus-end
+ const [selected, setSelected] = React.useState(listData[0].key);
+ const [isSelectionModeEnabled, setIsSelectionModeEnabled] =
+ React.useState(false);
+
+ // codeblock-focus-start
// ...
useFocusEffect(
React.useCallback(() => {
const onBackPress = () => {
- if (isSelectionModeEnabled()) {
- disableSelectionMode();
+ if (isSelectionModeEnabled) {
+ setIsSelectionModeEnabled(false);
return true;
} else {
return false;
}
};
- const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress);
+ const subscription = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ onBackPress
+ );
return () => subscription.remove();
- }, [isSelectionModeEnabled, disableSelectionMode])
+ }, [isSelectionModeEnabled])
+ );
+ // codeblock-focus-end
+
+ return (
+
+ {listData.map((item) => (
+ <>
+ {isSelectionModeEnabled ? (
+ {
+ setSelected(item.key);
+ }}
+ style={{
+ textDecorationLine: item.key === selected ? 'underline' : '',
+ }}
+ >
+
+ {item.key}
+
+
+ ) : (
+
+ {item.key === selected ? 'Selected: ' : ''}
+ {item.key}
+
+ )}
+ >
+ ))}
+ setIsSelectionModeEnabled(!isSelectionModeEnabled)}
+ >
+ Toggle selection mode
+
+ Selection mode: {isSelectionModeEnabled ? 'ON' : 'OFF'}
+
);
+ // codeblock-focus-start
// ...
}
+// codeblock-focus-end
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ CustomScreen: ScreenWithCustomBackBehavior,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ text: {
+ fontSize: 20,
+ marginBottom: 20,
+ },
+});
```
+
+
+
+```js name="Custom android back button" snack
+import * as React from 'react';
+import { Text, View, BackHandler, StyleSheet } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { useFocusEffect } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { PlatformPressable, Button } from '@react-navigation/elements';
+
+const Stack = createNativeStackNavigator();
+
+const listData = [{ key: 'Apple' }, { key: 'Orange' }, { key: 'Carrot' }];
+
+// codeblock-focus-start
+function ScreenWithCustomBackBehavior() {
+ // codeblock-focus-end
+
+ const [selected, setSelected] = React.useState(listData[0].key);
+ const [isSelectionModeEnabled, setIsSelectionModeEnabled] =
+ React.useState(false);
+ // codeblock-focus-start
+ // ...
+
+ useFocusEffect(
+ React.useCallback(() => {
+ const onBackPress = () => {
+ if (isSelectionModeEnabled) {
+ setIsSelectionModeEnabled(false);
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ const subscription = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ onBackPress
+ );
+
+ return () => subscription.remove();
+ }, [isSelectionModeEnabled])
+ );
+ // codeblock-focus-end
+
+ return (
+
+ {listData.map((item) => (
+ <>
+ {isSelectionModeEnabled ? (
+ {
+ setSelected(item.key);
+ }}
+ style={{
+ textDecorationLine: item.key === selected ? 'underline' : '',
+ }}
+ >
+
+ {item.key}
+
+
+ ) : (
+
+ {item.key === selected ? 'Selected: ' : ''}
+ {item.key}
+
+ )}
+ >
+ ))}
+ setIsSelectionModeEnabled(!isSelectionModeEnabled)}
+ >
+ Toggle selection mode
+
+ Selection mode: {isSelectionModeEnabled ? 'ON' : 'OFF'}
+
+ );
+ // codeblock-focus-start
+
+ // ...
+}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ text: {
+ fontSize: 20,
+ marginBottom: 20,
+ },
+});
+```
+
+
+
+
The presented approach will work well for screens that are shown in a `StackNavigator`. Custom back button handling in other situations may not be supported at the moment (eg. A known case when this does not work is when you want to handle back button press in an open drawer. PRs for such use cases are welcome!).
If instead of overriding system back button, you'd like to prevent going back from the screen, see docs for [preventing going back](preventing-going-back.md).
diff --git a/versioned_docs/version-7.x/custom-navigators.md b/versioned_docs/version-7.x/custom-navigators.md
index 606cd0fadda..5fa42e00ff1 100755
--- a/versioned_docs/version-7.x/custom-navigators.md
+++ b/versioned_docs/version-7.x/custom-navigators.md
@@ -4,26 +4,60 @@ title: Custom navigators
sidebar_label: Custom navigators
---
-Navigators allow you to define your application's navigation structure. Navigators also render common elements such as headers and tab bars which you can configure.
+In essence, a navigator is a React component that takes a set of screens and options, and renders them based on its [navigation state](navigation-state.md), generally with additional UI such as headers, tab bars, or drawers.
-Under the hood, navigators are plain React components.
+React Navigation provides a few built-in navigators, but they might not always fit your needs if you want a very custom behavior or UI. In such cases, you can build your own custom navigators using React Navigation's APIs.
-## Built-in Navigators
+A custom navigator behaves just like a built-in navigator, and can be used in the same way. This means you can define screens the same way, use [route](route-object.md) and [navigation](navigation-object.md) objects in your screens, and navigate between screens with familiar API. The navigator will also be able to handle deep linking, state persistence, and other features that built-in navigators support.
-We include some commonly needed navigators such as:
+## Overview
-- [`createStackNavigator`](stack-navigator.md) - Renders one screen at a time and provides transitions between screens. When a new screen is opened it is placed on top of the stack.
-- [`createDrawerNavigator`](drawer-navigator.md) - Provides a drawer that slides in from the left of the screen by default.
-- [`createBottomTabNavigator`](bottom-tab-navigator.md) - Renders a tab bar that lets the user switch between several screens.
-- [`createMaterialTopTabNavigator`](material-top-tab-navigator.md) - Renders tab view which lets the user switch between several screens using swipe gesture or the tab bar.
+Under the hood, navigators are plain React components that use the [`useNavigationBuilder`](#usenavigationbuilder) hook.
-## API for building custom navigators
+The navigator component then uses this state to layout the screens appropriately with any additional UI based on the use case. This component is then wrapped in [`createNavigatorFactory`](#createnavigatorfactory) to create the API for the navigator.
-A navigator bundles a router and a view which takes the [navigation state](navigation-state.md) and decides how to render it. We export a `useNavigationBuilder` hook to build custom navigators that integrate with rest of React Navigation.
+A very basic example looks like this:
+
+```js
+function MyStackNavigator(props) {
+ const { state, descriptors, NavigationContent } = useNavigationBuilder(
+ StackRouter,
+ props
+ );
+
+ const focusedRoute = state.routes[state.index];
+ const descriptor = descriptors[focusedRoute.key];
+
+ return {descriptor.render()} ;
+}
+
+export const createMyStackNavigator = createNavigatorFactory(MyStackNavigator);
+```
+
+Now, we have an already working navigator, even though it doesn't do anything special yet.
+
+Let's break this down:
+
+- We define a `MyNavigator` component that contains our navigator logic. This is the component that's rendered when you render `` in your app with the `createMyStackNavigator` factory function.
+- We use the `useNavigationBuilder` hook and pass it [`StackRouter`](custom-routers.md#built-in-routers), which would make our navigator behave like a stack navigator. Any other router such as `TabRouter`, `DrawerRouter`, or a custom router can be used here as well.
+- The hook returns the [navigation state](navigation-state.md) in the `state` property. This is the current state of the navigator. There's also a `descriptors` object which contains the data and helpers for each screen in the navigator.
+- We get the focused route from the state with `state.routes[state.index]` - as `state.index` is the index of the currently focused route in the `state.routes` array.
+- Then we get the corresponding descriptor for the focused route with `descriptors[focusedRoute.key]` and call the `render()` method on it to get the React element for the screen.
+- The content of the navigator is wrapped in `NavigationContent` to provide appropriate context and wrappers.
+
+With this, we have a basic stack navigator that renders only the focused screen. Unlike the built-in stack navigator, this doesn't keep unfocused screens rendered. But you can loop through `state.routes` and render all of the screens if you want to keep them mounted. You can also read `descriptor.options` to get the [options](screen-options.md) to handle the screen's title, header, and other options.
+
+This also doesn't have any additional UI apart from the screen content. There are no gestures or animations. So you're free to add any additional UI, gestures, animations etc. as needed. You can also layout the screens in any way you want, such as rendering them side-by-side or in a grid, instead of stacking them on top of each other like the built-in stack navigator does.
+
+You can see a more complete example of a custom navigator later in this document.
+
+## API Definition
### `useNavigationBuilder`
-This hook allows a component to hook into React Navigation. It accepts the following arguments:
+This hook contains the core logic of a navigator, and is responsible for storing and managing the [navigation state](navigation-state.md). It takes a [router](custom-routers.md) as an argument to know how to handle various navigation actions. It then returns the state and helper methods for the navigator component to use.
+
+It accepts the following arguments:
- `createRouter` - A factory method which returns a router object (e.g. `StackRouter`, `TabRouter`).
- `options` - Options for the hook and the router. The navigator should forward its props here so that user can provide props to configure the navigator. By default, the following options are accepted:
@@ -56,24 +90,14 @@ import {
TabActions,
} from '@react-navigation/native';
-function TabNavigator({
- initialRouteName,
- children,
- screenOptions,
- tabBarStyle,
- contentStyle,
-}) {
+function TabNavigator({ tabBarStyle, contentStyle, ...rest }) {
const { state, navigation, descriptors, NavigationContent } =
- useNavigationBuilder(TabRouter, {
- children,
- screenOptions,
- initialRouteName,
- });
+ useNavigationBuilder(TabRouter, rest);
return (
- {state.routes.map((route) => (
+ {state.routes.map((route, index) => (
{
@@ -145,9 +169,17 @@ import {
// ...
-export const createMyNavigator = createNavigatorFactory(TabNavigator);
+export function createMyNavigator(config) {
+ return createNavigatorFactory(TabNavigator)(config);
+}
```
+:::note
+
+We can also do `export const createMyNavigator = createNavigatorFactory(MyNavigator)` directly instead of wrapping in another function. However, the wrapper function is necessary to have proper [TypeScript support](#type-checking-navigators) for the navigator.
+
+:::
+
Then it can be used like this:
```js
@@ -181,23 +213,26 @@ import {
View,
Text,
Pressable,
- StyleProp,
- ViewStyle,
+ type StyleProp,
+ type ViewStyle,
StyleSheet,
} from 'react-native';
import {
createNavigatorFactory,
- DefaultNavigatorOptions,
- ParamListBase,
CommonActions,
- TabActionHelpers,
- TabNavigationState,
+ type DefaultNavigatorOptions,
+ type NavigatorTypeBagBase,
+ type ParamListBase,
+ type StaticConfig,
+ type TabActionHelpers,
+ type TabNavigationState,
TabRouter,
- TabRouterOptions,
+ type TabRouterOptions,
+ type TypedNavigator,
useNavigationBuilder,
} from '@react-navigation/native';
-// Props accepted by the view
+// Additional props accepted by the view
type TabNavigationConfig = {
tabBarStyle: StyleProp;
contentStyle: StyleProp;
@@ -209,7 +244,6 @@ type TabNavigationOptions = {
};
// Map of event name and the type of data (in event.data)
-//
// canPreventDefault: true adds the defaultPrevented property to the
// emitted events.
type TabNavigationEventMap = {
@@ -219,23 +253,34 @@ type TabNavigationEventMap = {
};
};
+// The type of the navigation object for each screen
+type TabNavigationProp<
+ ParamList extends ParamListBase,
+ RouteName extends keyof ParamList = keyof ParamList,
+ NavigatorID extends string | undefined = undefined,
+> = NavigationProp<
+ ParamList,
+ RouteName,
+ NavigatorID,
+ TabNavigationState,
+ TabNavigationOptions,
+ TabNavigationEventMap
+> &
+ TabActionHelpers;
+
// The props accepted by the component is a combination of 3 things
type Props = DefaultNavigatorOptions<
ParamListBase,
+ string | undefined,
TabNavigationState,
TabNavigationOptions,
- TabNavigationEventMap
+ TabNavigationEventMap,
+ TabNavigationProp
> &
TabRouterOptions &
TabNavigationConfig;
-function TabNavigator({
- initialRouteName,
- children,
- screenOptions,
- tabBarStyle,
- contentStyle,
-}: Props) {
+function TabNavigator({ tabBarStyle, contentStyle, ...rest }: Props) {
const { state, navigation, descriptors, NavigationContent } =
useNavigationBuilder<
TabNavigationState,
@@ -243,11 +288,7 @@ function TabNavigator({
TabActionHelpers,
TabNavigationOptions,
TabNavigationEventMap
- >(TabRouter, {
- children,
- screenOptions,
- initialRouteName,
- });
+ >(TabRouter, rest);
return (
@@ -298,12 +339,29 @@ function TabNavigator({
);
}
-export default createNavigatorFactory<
- TabNavigationState,
- TabNavigationOptions,
- TabNavigationEventMap,
- typeof TabNavigator
->(TabNavigator);
+// The factory function with generic types for type-inference
+export function createMyNavigator<
+ const ParamList extends ParamListBase,
+ const NavigatorID extends string | undefined = undefined,
+ const TypeBag extends NavigatorTypeBagBase = {
+ ParamList: ParamList;
+ NavigatorID: NavigatorID;
+ State: TabNavigationState;
+ ScreenOptions: TabNavigationOptions;
+ EventMap: TabNavigationEventMap;
+ NavigationList: {
+ [RouteName in keyof ParamList]: TabNavigationProp<
+ ParamList,
+ RouteName,
+ NavigatorID
+ >;
+ };
+ Navigator: typeof TabNavigator;
+ },
+ const Config extends StaticConfig = StaticConfig,
+>(config?: Config): TypedNavigator {
+ return createNavigatorFactory(TabNavigator)(config);
+}
```
## Extending Navigators
@@ -320,18 +378,26 @@ import {
import { BottomTabView } from '@react-navigation/bottom-tabs';
function BottomTabNavigator({
+ id,
initialRouteName,
- backBehavior,
children,
+ layout,
+ screenListeners,
screenOptions,
+ screenLayout,
+ backBehavior,
...rest
}) {
const { state, descriptors, navigation, NavigationContent } =
useNavigationBuilder(TabRouter, {
+ id,
initialRouteName,
- backBehavior,
children,
+ layout,
+ screenListeners,
screenOptions,
+ screenLayout,
+ backBehavior,
});
return (
@@ -346,7 +412,9 @@ function BottomTabNavigator({
);
}
-export default createNavigatorFactory(BottomTabNavigator);
+export function createMyNavigator(config) {
+ return createNavigatorFactory(TabNavigator)(config);
+}
```
Now, we can customize it to add additional functionality or change the behavior. For example, use a [custom router](custom-routers.md) instead of the default `TabRouter`:
@@ -358,11 +426,26 @@ import MyRouter from './MyRouter';
const { state, descriptors, navigation, NavigationContent } =
useNavigationBuilder(MyRouter, {
+ id,
initialRouteName,
- backBehavior,
children,
+ layout,
+ screenListeners,
screenOptions,
+ screenLayout,
+ backBehavior,
});
// ...
```
+
+:::note
+
+Customizing built-in navigators like this is an advanced use case and generally not necessary. Consider alternatives such as:
+
+- [`layout`](navigator.md#layout) prop on navigators to add a wrapper around the navigator
+- [`UNSTABLE_router`](navigator.md#router) prop on navigators to customize the router behavior
+
+Also refer to the navigator's documentation to see if any existing API meets your needs.
+
+:::
diff --git a/versioned_docs/version-7.x/custom-routers.md b/versioned_docs/version-7.x/custom-routers.md
index 02ca5f30b47..86b66d3a1f9 100755
--- a/versioned_docs/version-7.x/custom-routers.md
+++ b/versioned_docs/version-7.x/custom-routers.md
@@ -11,14 +11,20 @@ The router is responsible for handling actions dispatched by calling methods on
You can make your own router by building an object with the following functions:
- `type` - String representing the type of the router, e.g. `'stack'`, `'tab'`, `'drawer'` etc.
-- `getInitialState` - Function which returns the initial state for the navigator. Receives an options object with `routeNames` and `routeParamList` properties.
-- `getRehydratedState` - Function which rehydrates the full [navigation state](navigation-state.md) from a given partial state. Receives a partial state object and an options object with `routeNames` and `routeParamList` properties.
-- `getStateForRouteNamesChange` - Function which takes the current state and updated list of route names, and returns a new state. Receives the state object and an options object with `routeNames` and `routeParamList` properties.
-- `getStateForAction` - function which takes the current state and action along with an options object with `routeNames` and `routeParamList` properties, and returns a new state. If the action cannot be handled, it should return `null`.
-- `getStateForRouteFocus` - Function which takes the current state and key of a route, and returns a new state with that route focused.
-- `shouldActionChangeFocus` - Function which determines whether the action should also change focus in parent navigator. Some actions such as `NAVIGATE` can change focus in the parent.
+- `getInitialState` - Function that returns the initial state for the navigator. Receives an options object with `routeNames` and `routeParamList` properties.
+- `getRehydratedState` - Function that rehydrates the full [navigation state](navigation-state.md) from a given partial state. Receives a partial state object and an options object with `routeNames` and `routeParamList` properties.
+- `getStateForRouteNamesChange` - Function that takes the current state and updated list of route names, and returns a new state. Receives the state object and an options object with `routeNames` and `routeParamList` properties.
+- `getStateForAction` - Reducer function that takes the current state and action along with an options object with `routeNames` and `routeParamList` properties, and returns a new state. If the action cannot be handled, it should return `null`.
+- `getStateForRouteFocus` - Function that takes the current state and key of a route, and returns a new state with that route focused.
+- `shouldActionChangeFocus` - Function that determines whether the action should also change focus in parent navigator. Some actions such as `NAVIGATE` can change focus in the parent.
- `actionCreators` - Optional object containing a list of action creators, such as `push`, `pop` etc. These will be used to add helper methods to the `navigation` object to dispatch those actions.
+:::info
+
+The functions in the router object should be pure functions, i.e. they should not have any side-effects, mutate parameters or external variables, and should return the same output for the same input.
+
+:::
+
Example:
```js
@@ -144,9 +150,10 @@ The library ships with a few standard routers:
## Customizing Routers
-You can reuse a router and override the router functions as per your needs, such as customizing how existing actions are handled, adding additional actions etc.
+There are two main ways to customize routers:
-See [custom navigators](custom-navigators.md) for details on how to override the router with a custom router in an existing navigator.
+- Override an existing router with the [`UNSTABLE_router`](navigator.md#router) prop on navigators
+- Customized navigators with a custom router, see [extending navigators](custom-navigators.md#extending-navigators)
### Custom Navigation Actions
@@ -155,7 +162,7 @@ Let's say you want to add a custom action to clear the history:
```js
import { TabRouter } from '@react-navigation/native';
-const MyTabRouter = options => {
+const MyTabRouter = (options) => {
const router = TabRouter(options);
return {
@@ -191,7 +198,7 @@ Sometimes you may want to prevent some navigation activity, depending on your ro
```js
import { StackRouter } from '@react-navigation/native';
-const MyStackRouter = options => {
+const MyStackRouter = (options) => {
const router = StackRouter(options);
return {
@@ -214,4 +221,4 @@ const MyStackRouter = options => {
};
```
-If you want to prevent going back, the recommended approach is to use the [`beforeRemove` event](preventing-going-back.md).
+If you want to prevent going back, the recommended approach is to use the [`usePreventRemove` hook](preventing-going-back.md).
diff --git a/versioned_docs/version-7.x/customizing-bottom-tabs.md b/versioned_docs/version-7.x/customizing-bottom-tabs.md
new file mode 100755
index 00000000000..4f17f068c5e
--- /dev/null
+++ b/versioned_docs/version-7.x/customizing-bottom-tabs.md
@@ -0,0 +1,290 @@
+---
+id: customizing-tabbar
+title: Customizing bottom tab bar
+sidebar_label: Customizing tab bar
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+This guide covers customizing the tab bar in [`createBottomTabNavigator`](bottom-tab-navigator.md). Make sure to install and configure the library according to the [installation instructions](bottom-tab-navigator.md#installation) first.
+
+## Add icons for each tab
+
+This is similar to how you would customize a stack navigator — there are some properties that are set when you initialize the tab navigator and others that can be customized per-screen in `options`.
+
+
+
+
+```js name="Tab bar icons" snack dependencies=@expo/vector-icons,@expo/vector-icons/Ionicons
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+// codeblock-focus-start
+// You can import Ionicons from @expo/vector-icons/Ionicons if you use Expo or
+// react-native-vector-icons/Ionicons otherwise.
+import Ionicons from 'react-native-vector-icons/Ionicons';
+
+// codeblock-focus-end
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function SettingsScreen() {
+ return (
+
+ Settings!
+
+ );
+}
+
+// codeblock-focus-start
+const RootTabs = createBottomTabNavigator({
+ screenOptions: ({ route }) => ({
+ // highlight-start
+ tabBarIcon: ({ focused, color, size }) => {
+ let iconName;
+
+ if (route.name === 'Home') {
+ iconName = focused
+ ? 'ios-information-circle'
+ : 'ios-information-circle-outline';
+ } else if (route.name === 'Settings') {
+ iconName = focused ? 'ios-list' : 'ios-list-outline';
+ }
+
+ // You can return any component that you like here!
+ return ;
+ },
+ // highlight-end
+ tabBarActiveTintColor: 'tomato',
+ tabBarInactiveTintColor: 'gray',
+ }),
+ screens: {
+ Home: HomeScreen,
+ Settings: SettingsScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Tab based navigation" snack dependencies=@expo/vector-icons,@expo/vector-icons/Ionicons
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+// codeblock-focus-start
+// You can import Ionicons from @expo/vector-icons/Ionicons if you use Expo or
+// react-native-vector-icons/Ionicons otherwise.
+import Ionicons from 'react-native-vector-icons/Ionicons';
+
+// codeblock-focus-end
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function SettingsScreen() {
+ return (
+
+ Settings!
+
+ );
+}
+
+const Tab = createBottomTabNavigator();
+
+// codeblock-focus-start
+function RootTabs() {
+ return (
+ ({
+ // highlight-start
+ tabBarIcon: ({ focused, color, size }) => {
+ let iconName;
+
+ if (route.name === 'Home') {
+ iconName = focused
+ ? 'ios-information-circle'
+ : 'ios-information-circle-outline';
+ } else if (route.name === 'Settings') {
+ iconName = focused ? 'ios-list' : 'ios-list-outline';
+ }
+
+ // You can return any component that you like here!
+ return ;
+ },
+ // highlight-end
+ tabBarActiveTintColor: 'tomato',
+ tabBarInactiveTintColor: 'gray',
+ })}
+ >
+
+
+
+ );
+}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
+Let's dissect this:
+
+- `tabBarIcon` is a supported option in bottom tab navigator. So we know we can use it on our screen components in the `options` prop, but in this case chose to put it in the `screenOptions` prop of `Tab.Navigator` in order to centralize the icon configuration for convenience.
+- `tabBarIcon` is a function that is given the `focused` state, `color`, and `size` params. If you take a peek further down in the configuration you will see `tabBarActiveTintColor` and `tabBarInactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `color` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active). The `size` is the size of the icon expected by the tab bar.
+- Read the [full API reference](bottom-tab-navigator.md) for further information on `createBottomTabNavigator` configuration options.
+
+## Add badges to icons
+
+Sometimes we want to add badges to some icons. You can use the [`tabBarBadge` option](bottom-tab-navigator.md#tabbarbadge) to do it:
+
+
+
+
+```js name="Tab based navigation" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function SettingsScreen() {
+ return (
+
+ Settings!
+
+ );
+}
+
+// codeblock-focus-start
+const RootTabs = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ // highlight-start
+ tabBarBadge: 3,
+ // highlight-end
+ },
+ },
+ Settings: SettingsScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Tab based navigation" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+function HomeScreen() {
+ return (
+
+ Home!
+
+ );
+}
+
+function SettingsScreen() {
+ return (
+
+ Settings!
+
+ );
+}
+
+const Tab = createBottomTabNavigator();
+
+// codeblock-focus-start
+function RootTabs() {
+ return (
+
+
+
+
+ );
+}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
+From UI perspective this component is ready to use, but you still need to find some way to pass down the badge count properly from somewhere else, like using [React Context](https://react.dev/reference/react/useContext), [Redux](https://redux.js.org/), [MobX](https://mobx.js.org/) or [event emitters](https://github.com/facebook/react-native/blob/master/Libraries/vendor/emitter/EventEmitter.js).
+
+You can also update the badge from within the screen component by using the `setOptions` method:
+
+```js
+const navigation = useNavigation();
+
+React.useEffect(() => {
+ navigation.setOptions({
+ tabBarBadge: unreadMessagesCount,
+ });
+}, [navigation, unreadMessagesCount]);
+```
+
+
diff --git a/versioned_docs/version-7.x/deep-linking.md b/versioned_docs/version-7.x/deep-linking.md
index 29e8c1b75c5..2dcac6d9f96 100755
--- a/versioned_docs/version-7.x/deep-linking.md
+++ b/versioned_docs/version-7.x/deep-linking.md
@@ -4,6 +4,9 @@ title: Deep linking
sidebar_label: Deep linking
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
This guide will describe how to configure your app to handle deep links on various platforms. To handle incoming links, you need to handle 2 scenarios:
1. If the app wasn't previously open, the deep link needs to set the initial state
@@ -15,14 +18,19 @@ While you don't need to use the `linking` prop from React Navigation, and can ha
Below, we'll go through required configurations so that the deep link integration works.
-## Setup with Expo projects
+## Setting up deep links
+
+
+
-First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `mychat` then a link to your app would be `mychat://`. You can register for a scheme in your `app.json` by adding a string under the scheme key:
+### Configuring URL scheme
+
+First, you will want to specify a URL scheme for your app. This corresponds to the string before `://` in a URL, so if your scheme is `example` then a link to your app would be `example://`. You can register for a scheme in your `app.json` by adding a string under the scheme key:
```json
{
"expo": {
- "scheme": "mychat"
+ "scheme": "example"
}
}
```
@@ -33,30 +41,25 @@ Next, install `expo-linking` which we'd need to get the deep link prefix:
npx expo install expo-linking
```
-Then, let's configure React Navigation to use the `scheme` for parsing incoming deep links:
+Then you can use `Linking.createURL` to get the prefix for your app:
```js
-import * as Linking from 'expo-linking';
-
-const prefix = Linking.createURL('/');
+const linking = {
+ prefixes: [Linking.createURL('/'),
+};
+```
-function App() {
- const linking = {
- prefixes: [prefix],
- };
+See more details below at [Configuring React Navigation](#configuring-react-navigation).
- return (
- Loading...}>
- {/* content */}
-
- );
-}
-```
+
+Why use `Linking.createURL`?
-The reason that is necessary to use `Linking.createURL` is that the scheme will differ depending on whether you're in the client app or in a standalone app.
+It is necessary to use `Linking.createURL` since the scheme differs between the [Expo Dev Client](https://docs.expo.dev/versions/latest/sdk/dev-client/) and standalone apps.
The scheme specified in `app.json` only applies to standalone apps. In the Expo client app you can deep link using `exp://ADDRESS:PORT/--/` where `ADDRESS` is often `127.0.0.1` and `PORT` is often `19000` - the URL is printed when you run `expo start`. The `Linking.createURL` function abstracts it out so that you don't need to specify them manually.
+
+
If you are using universal links, you need to add your domain to the prefixes as well:
```js
@@ -65,19 +68,81 @@ const linking = {
};
```
-## Set up with bare React Native projects
+### Universal Links on iOS
+
+To set up iOS universal Links in your Expo app, you need to configure your [app config](https://docs.expo.dev/workflow/configuration) to include the associated domains and entitlements:
+
+```json
+{
+ "expo": {
+ "ios": {
+ "associatedDomains": ["applinks:app.example.com"],
+ "entitlements": {
+ "com.apple.developer.associated-domains": ["applinks:app.example.com"]
+ }
+ }
+ }
+}
+```
+
+You will also need to setup [Associated Domains](https://developer.apple.com/documentation/Xcode/supporting-associated-domains) on your server.
+
+See [Expo's documentation on iOS Universal Links](https://docs.expo.dev/linking/ios-universal-links/) for more details.
+
+### App Links on Android
+
+To set up Android App Links in your Expo app, you need to configure your [app config](https://docs.expo.dev/workflow/configuration) to include the `intentFilters`:
+
+```json
+{
+ "expo": {
+ "android": {
+ "intentFilters": [
+ {
+ "action": "VIEW",
+ "autoVerify": true,
+ "data": [
+ {
+ "scheme": "https",
+ "host": "app.example.com"
+ }
+ ],
+ "category": ["BROWSABLE", "DEFAULT"]
+ }
+ ]
+ }
+ }
+}
+```
+
+You will also need to [declare the association](https://developer.android.com/training/app-links/verify-android-applinks#web-assoc) between your website and your intent filters by hosting a Digital Asset Links JSON file.
+
+See [Expo's documentation on Android App Links](https://docs.expo.dev/linking/android-app-links/) for more details.
+
+
+
### Setup on iOS
-Let's configure the native iOS app to open based on the `mychat://` URI scheme.
+Let's configure the native iOS app to open based on the `example://` URI scheme.
+
+You'll need to add the `LinkingIOS` folder into your header search paths as described [here](https://reactnative.dev/docs/linking-libraries-ios#step-3). Then you'll need to add the following lines to your or `AppDelegate.swift` or `AppDelegate.mm` file:
+
+
+
+
+```swift
+func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
+ return RCTLinkingManager.application(app, open: url, options: options)
+}
+```
-You'll need to link `RCTLinking` to your project by following the steps described here. To be able to listen to incoming app links, you'll need to add the following lines to `AppDelegate.m` in your project:
+
+
```objc
-// Add the header at the top of the file:
#import
-// Add this inside `@implementation AppDelegate` above `@end`:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary *)options
@@ -86,10 +151,31 @@ You'll need to link `RCTLinking` to your project by following the steps describe
}
```
+
+
+
If your app is using [Universal Links](https://developer.apple.com/ios/universal-links/), you'll need to add the following code as well:
+
+
+
+```swift
+func application(
+ _ application: UIApplication,
+ continue userActivity: NSUserActivity,
+ restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
+ return RCTLinkingManager.application(
+ application,
+ continue: userActivity,
+ restorationHandler: restorationHandler
+ )
+ }
+```
+
+
+
+
```objc
-// Add this inside `@implementation AppDelegate` above `@end`:
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler
{
@@ -99,17 +185,20 @@ If your app is using [Universal Links](https://developer.apple.com/ios/universal
}
```
+
+
+
Now you need to add the scheme to your project configuration.
The easiest way to do this is with the `uri-scheme` package by running the following:
```bash
-npx uri-scheme add mychat --ios
+npx uri-scheme add example --ios
```
If you want to do it manually, open the project (e.g. `SimpleApp/ios/SimpleApp.xcworkspace`) in Xcode. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.
-
+
To make sure Universal Links work in your app, you also need to setup [Associated Domains](https://developer.apple.com/documentation/Xcode/supporting-associated-domains) on your server.
@@ -129,7 +218,7 @@ If you're using React Navigation within a hybrid app - an iOS app that has both
To configure the external linking in Android, you can create a new intent in the manifest.
-The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add mychat --android`.
+The easiest way to do this is with the `uri-scheme` package: `npx uri-scheme add example --android`.
If you want to add it manually, open up `SimpleApp/android/app/src/main/AndroidManifest.xml`, and make the following adjustments:
@@ -148,12 +237,12 @@ If you want to add it manually, open up `SimpleApp/android/app/src/main/AndroidM
-
+
```
-Similar to Universal Links on iOS, you can also use a domain to associate the app with your website on Android by [verifying Android App Links](https://developer.android.com/training/app-links/verify-site-associations). First, you need to configure your `AndroidManifest.xml`:
+Similar to Universal Links on iOS, you can also use a domain to associate the app with your website on Android by [verifying Android App Links](https://developer.android.com/training/app-links/verify-android-applinks). First, you need to configure your `AndroidManifest.xml`:
1. Add `android:autoVerify="true"` to your `` entry.
2. Add your domain's `scheme` and `host` in a new `` entry inside the ``.
@@ -164,7 +253,7 @@ After adding them, it should look like this:
-
+
@@ -172,20 +261,77 @@ After adding them, it should look like this:
-
+
-
+
-
+
```
-Then, you need to [declare the association](https://developer.android.com/training/app-links/verify-site-associations#web-assoc) between your website and your intent filters by hosting a Digital Asset Links JSON file.
+Then, you need to [declare the association](https://developer.android.com/training/app-links/verify-android-applinks#web-assoc) between your website and your intent filters by hosting a Digital Asset Links JSON file.
+
+
+
+
+## Configuring React Navigation
+
+To handle deep links, you need to configure React Navigation to use the `scheme` for parsing incoming deep links:
+
+
+
+
+```js
+const linking = {
+ prefixes: [
+ 'example://', // Or `Linking.createURL('/')` for Expo apps
+ ],
+};
+
+function App() {
+ return ;
+}
+```
+
+
+
+
+```js
+const linking = {
+ prefixes: [
+ 'example://', // Or `Linking.createURL('/')` for Expo apps
+ ],
+};
+
+function App() {
+ return (
+ Loading...}>
+ {/* content */}
+
+ );
+}
+```
+
+
+
+
+If you are using universal links, you need to add your domain to the prefixes as well:
+
+```js
+const linking = {
+ prefixes: [
+ 'example://', // Or `Linking.createURL('/')` for Expo apps
+ 'https://app.example.com',
+ ],
+};
+```
+
+See [configuring links](configuring-links.md) to see further details on how to configure links in React Navigation.
## Testing deep links
@@ -203,7 +349,7 @@ If you're testing on Android, run:
npx react-native run-android
```
-If you're using Expo managed workflow and testing on Expo client, you don't need to rebuild the app. However, you will need to use the correct address and port that's printed when you run `expo start` ([see above](#setup-with-expo-projects)), e.g. `exp://127.0.0.1:19000/--/`.
+If you're using Expo managed workflow and testing on Expo client, you don't need to rebuild the app. However, you will need to use the correct address and port that's printed when you run `expo start`, e.g. `exp://127.0.0.1:19000/--/`.
If you want to test with your custom scheme in your Expo app, you will need rebuild your standalone app by running `expo build:ios -t simulator` or `expo build:android` and install the resulting binaries.
@@ -218,7 +364,7 @@ npx uri-scheme open [your deep link] --[ios|android]
For example:
```bash
-npx uri-scheme open "mychat://chat/jane" --ios
+npx uri-scheme open "example://chat/jane" --ios
```
Or if using Expo client:
@@ -238,7 +384,7 @@ xcrun simctl openurl booted [your deep link]
For example:
```bash
-xcrun simctl openurl booted "mychat://chat/jane"
+xcrun simctl openurl booted "example://chat/jane"
```
### Testing with `adb` on Android
@@ -252,7 +398,7 @@ adb shell am start -W -a android.intent.action.VIEW -d [your deep link] [your an
For example:
```bash
-adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/jane" com.simpleapp
+adb shell am start -W -a android.intent.action.VIEW -d "example://chat/jane" com.simpleapp
```
Or if using Expo client:
@@ -261,53 +407,101 @@ Or if using Expo client:
adb shell am start -W -a android.intent.action.VIEW -d "exp://127.0.0.1:19000/--/chat/jane" host.exp.exponent
```
-## Third-party integrations
+## Integrating with other tools
-React Native's `Linking` isn't the only way to handle deep linking. You might also want to integrate other services such as [Firebase Dynamic Links](https://firebase.google.com/docs/dynamic-links), [Branch](https://help.branch.io/developers-hub/docs/react-native) etc. which provide their own API for getting notified of incoming links.
+In addition to deep links and universal links with React Native's `Linking` API, you may also want to integrate other tools for handling incoming links, e.g. Push Notifications - so that tapping on a notification can open the app to a specific screen.
-To achieve this, you'd need to override how React Navigation subscribes to incoming links. To do so, you can provide your own [`getInitialURL`](navigation-container.md#linkinggetinitialurl) and [`subscribe`](navigation-container.md#linkingsubscribe) functions:
+To achieve this, you'd need to override how React Navigation subscribes to incoming links. To do so, you can provide your own [`getInitialURL`](navigation-container.md#linkinggetinitialurl) and [`subscribe`](navigation-container.md#linkingsubscribe) functions.
-```js
+Here is an example integration with [expo-notifications](https://docs.expo.dev/versions/latest/sdk/notifications):
+
+
+
+
+```js name="Expo Notifications"
const linking = {
- prefixes: ['myapp://', 'https://myapp.com'],
+ prefixes: ['example://', 'https://app.example.com'],
// Custom function to get the URL which was used to open the app
async getInitialURL() {
- // First, you would need to get the initial URL from your third-party integration
- // The exact usage depend on the third-party SDK you use
- // For example, to get the initial URL for Firebase Dynamic Links:
- const { isAvailable } = utils().playServicesAvailability;
-
- if (isAvailable) {
- const initialLink = await dynamicLinks().getInitialLink();
+ // First, handle deep links
+ const url = await Linking.getInitialURL();
- if (initialLink) {
- return initialLink.url;
- }
+ if (url != null) {
+ return url;
}
- // As a fallback, you may want to do the default deep link handling
- const url = await Linking.getInitialURL();
+ // Handle URL from expo push notifications
+ const response = await Notifications.getLastNotificationResponseAsync();
- return url;
+ return response?.notification.request.content.data.url;
},
// Custom function to subscribe to incoming links
subscribe(listener) {
- // Listen to incoming links from Firebase Dynamic Links
- const unsubscribeFirebase = dynamicLinks().onLink(({ url }) => {
+ // Listen to incoming links for deep links
+ const linkingSubscription = Linking.addEventListener('url', ({ url }) => {
listener(url);
});
- // Listen to incoming links from deep linking
+ // Listen to expo push notifications when user interacts with them
+ const pushNotificationSubscription =
+ Notifications.addNotificationResponseReceivedListener((response) => {
+ const url = response.notification.request.content.data.url;
+
+ listener(url);
+ });
+
+ return () => {
+ // Clean up the event listeners
+ linkingSubscription.remove();
+ pushNotificationSubscription.remove();
+ };
+ },
+};
+```
+
+
+
+
+```js name="Expo Notifications"
+const linking = {
+ prefixes: ['example://', 'https://app.example.com'],
+
+ // Custom function to get the URL which was used to open the app
+ async getInitialURL() {
+ // First, handle deep links
+ const url = await Linking.getInitialURL();
+
+ if (url != null) {
+ return url;
+ }
+
+ // Handle URL from expo push notifications
+ const response = await Notifications.getLastNotificationResponseAsync();
+
+ return response?.notification.request.content.data.url;
+ },
+
+ // Custom function to subscribe to incoming links
+ subscribe(listener) {
+ // Listen to incoming links for deep links
const linkingSubscription = Linking.addEventListener('url', ({ url }) => {
listener(url);
});
+ // Listen to expo push notifications when user interacts with them
+ const pushNotificationSubscription =
+ Notifications.addNotificationResponseReceivedListener((response) => {
+ const url = response.notification.request.content.data.url;
+
+ listener(url);
+ });
+
return () => {
// Clean up the event listeners
- unsubscribeFirebase();
linkingSubscription.remove();
+ pushNotificationSubscription.remove();
};
},
@@ -317,4 +511,7 @@ const linking = {
};
```
+
+
+
Similar to the above example, you can integrate any API that provides a way to get the initial URL and to subscribe to new incoming URLs using the `getInitialURL` and `subscribe` options.
diff --git a/versioned_docs/version-7.x/devtools.md b/versioned_docs/version-7.x/devtools.md
index ad15c800dca..692ae42369b 100644
--- a/versioned_docs/version-7.x/devtools.md
+++ b/versioned_docs/version-7.x/devtools.md
@@ -4,12 +4,15 @@ title: Developer tools
sidebar_label: Developer tools
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Developer tools to make debugging easier when using React Navigation.
To use the developer tools, install [`@react-navigation/devtools`](https://github.com/react-navigation/react-navigation/tree/master/packages/devtools):
```bash npm2yarn
-npm install @react-navigation/devtools@next
+npm install @react-navigation/devtools
```
Hooks from this package only work during development and are disabled in production. You don't need to do anything special to remove them from the production build.
@@ -18,6 +21,67 @@ Hooks from this package only work during development and are disabled in product
The package exposes the following APIs:
+### `useLogger`
+
+This hook provides a logger for React Navigation. It logs the navigation state and actions to the console.
+
+
+
+
+
+
+**Usage:**
+
+To use the hook, import it and pass a `ref` to the `NavigationContainer` as its argument:
+
+
+
+
+```js
+import * as React from 'react';
+import {
+ createStaticNavigation,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
+import { useLogger } from '@react-navigation/devtools';
+
+/* content */
+
+export default function App() {
+ const navigationRef = useNavigationContainerRef();
+
+ useLogger(navigationRef);
+
+ return ;
+}
+```
+
+
+
+
+
+```js
+import * as React from 'react';
+import {
+ NavigationContainer,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
+import { useLogger } from '@react-navigation/devtools';
+
+export default function App() {
+ const navigationRef = useNavigationContainerRef();
+
+ useLogger(navigationRef);
+
+ return (
+ {/* ... */}
+ );
+}
+```
+
+
+
+
### `useReduxDevToolsExtension`
This hook provides integration with [Redux DevTools Extension](https://github.com/reduxjs/redux-devtools). It also works with [`React Native Debugger app`](https://github.com/jhen0409/react-native-debugger) which includes this extension.
@@ -26,9 +90,38 @@ This hook provides integration with [Redux DevTools Extension](https://github.co
To use the hook, import it and pass a `ref` to the `NavigationContainer` as its argument:
+
+
+
```js
import * as React from 'react';
-import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
+import {
+ createStaticNavigation,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
+import { useReduxDevToolsExtension } from '@react-navigation/devtools';
+
+/* content */
+
+export default function App() {
+ const navigationRef = useNavigationContainerRef();
+
+ useReduxDevToolsExtension(navigationRef);
+
+ return ;
+}
+```
+
+
+
+
+
+```js
+import * as React from 'react';
+import {
+ NavigationContainer,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
import { useReduxDevToolsExtension } from '@react-navigation/devtools';
export default function App() {
@@ -42,4 +135,7 @@ export default function App() {
}
```
+
+
+
Now, you'll be able to see logs from React Navigation in Redux DevTools Extension, e.g. when you're debugging your app with React Native Debugger app.
diff --git a/versioned_docs/version-7.x/drawer-actions.md b/versioned_docs/version-7.x/drawer-actions.md
index 1495998a2b9..0500a6312c1 100755
--- a/versioned_docs/version-7.x/drawer-actions.md
+++ b/versioned_docs/version-7.x/drawer-actions.md
@@ -4,6 +4,9 @@ title: DrawerActions reference
sidebar_label: DrawerActions
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`DrawerActions` is an object containing methods for generating actions specific to drawer-based navigators. Its methods expand upon the actions available in [CommonActions](navigation-actions.md).
The following actions are supported:
@@ -12,38 +15,531 @@ The following actions are supported:
The `openDrawer` action can be used to open the drawer pane.
-
+
+
+
+```js name="Drawer Actions - openDrawer" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ DrawerActions,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.openDrawer());
+ // codeblock-focus-end
+ }}
+ >
+ Open Drawer
+
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle Drawer
+
+ navigation.dispatch(jumpToAction)}>
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Drawer Actions - openDrawer" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ DrawerActions,
+ useNavigation,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.openDrawer());
+ // codeblock-focus-end
+ }}
+ >
+ Open Drawer
+
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle Drawer
+
+ navigation.dispatch(jumpToAction)}>
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
-```js
-import { DrawerActions } from '@react-navigation/native';
+const Drawer = createDrawerNavigator();
-navigation.dispatch(DrawerActions.openDrawer());
+export default function App() {
+ return (
+
+ }
+ >
+
+
+
+
+ );
+}
```
+
+
+
### closeDrawer
The `closeDrawer` action can be used to close the drawer pane.
-
+
+
+
+```js name="Drawer Actions - closeDrawer" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ DrawerActions,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open Drawer
+
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle Drawer
+
+ navigation.dispatch(jumpToAction)}>
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent({ navigation }) {
+ return (
+
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.closeDrawer());
+ // codeblock-focus-end
+ }}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Drawer Actions - closeDrawer" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ DrawerActions,
+ useNavigation,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open Drawer
+
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle Drawer
+
+ navigation.dispatch(jumpToAction)}>
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent({ navigation }) {
+ return (
+
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.closeDrawer());
+ // codeblock-focus-end
+ }}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
-```js
-import { DrawerActions } from '@react-navigation/native';
+const Drawer = createDrawerNavigator();
-navigation.dispatch(DrawerActions.closeDrawer());
+export default function App() {
+ return (
+
+ }
+ >
+
+
+
+
+ );
+}
```
+
+
+
### toggleDrawer
The `toggleDrawer` action can be used to open the drawer pane if closed, or close if open.
-
+
+
+
+```js name="Drawer Actions - toggleDrawer" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ DrawerActions,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open Drawer
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.toggleDrawer());
+ // codeblock-focus-end
+ }}
+ >
+ Toggle Drawer
+
+ navigation.dispatch(jumpToAction)}>
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Drawer Actions - toggleDrawer" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ DrawerActions,
+ useNavigation,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen({ navigation }) {
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open Drawer
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.toggleDrawer());
+ // codeblock-focus-end
+ }}
+ >
+ Toggle Drawer
+
+ navigation.dispatch(jumpToAction)}>
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
-```js
-import { DrawerActions } from '@react-navigation/native';
+const Drawer = createDrawerNavigator();
-navigation.dispatch(DrawerActions.toggleDrawer());
+export default function App() {
+ return (
+
+ }
+ >
+
+
+
+
+ );
+}
```
+
+
+
### jumpTo
The `jumpTo` action can be used to jump to an existing route in the drawer navigator.
@@ -51,12 +547,175 @@ The `jumpTo` action can be used to jump to an existing route in the drawer navig
- `name` - _string_ - Name of the route to jump to.
- `params` - _object_ - Screen params to pass to the destination route.
-
+
+
+
+```js name="Drawer Actions - jumpTo" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ DrawerActions,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open Drawer
+
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle Drawer
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(jumpToAction);
+ // codeblock-focus-end
+ }}
+ >
+ Jump to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
-```js
-import { DrawerActions } from '@react-navigation/native';
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Drawer Actions - jumpTo" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ DrawerActions,
+ useNavigation,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+
+function HomeScreen({ navigation }) {
+ const jumpToAction = DrawerActions.jumpTo('Profile', { user: 'Satya' });
-const jumpToAction = DrawerActions.jumpTo('Profile', { name: 'Satya' });
+ return (
+
+ Home!
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open Drawer
+
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle Drawer
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(jumpToAction);
+ // codeblock-focus-end
+ }}
+ >
+ Jump to Profile
+
+
+ );
+}
-navigation.dispatch(jumpToAction);
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+
+export default function App() {
+ return (
+
+ }
+ >
+
+
+
+
+ );
+}
```
+
+
+
diff --git a/versioned_docs/version-7.x/drawer-based-navigation.md b/versioned_docs/version-7.x/drawer-based-navigation.md
index 46b3c9b6994..d760ff5d33c 100755
--- a/versioned_docs/version-7.x/drawer-based-navigation.md
+++ b/versioned_docs/version-7.x/drawer-based-navigation.md
@@ -4,13 +4,14 @@ title: Drawer navigation
sidebar_label: Drawer navigation
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Common pattern in navigation is to use drawer from left (sometimes right) side for navigating between screens.
-
-
-
-
-
+
+
+
Before continuing, first install and configure [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer) and its dependencies following the [installation instructions](drawer-navigator.md#installation).
@@ -19,29 +20,83 @@ Before continuing, first install and configure [`@react-navigation/drawer`](http
To use this drawer navigator, import it from `@react-navigation/drawer`:
(swipe right to open)
-
+
+
-```js
+```js name="Drawer navigation" snack
import * as React from 'react';
-import { Button, View } from 'react-native';
+import { View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
-import { NavigationContainer } from '@react-navigation/native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
-function HomeScreen({ navigation }) {
return (
- navigation.navigate('Notifications')}
- title="Go to notifications"
- />
+ navigation.navigate('Notifications')}>
+ Go to notifications
+
+
+ );
+}
+
+function NotificationsScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.goBack()}>Go back home
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ screens: {
+ Home: HomeScreen,
+ Notifications: NotificationsScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Drawer navigation" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Notifications')}>
+ Go to notifications
+
);
}
-function NotificationsScreen({ navigation }) {
+function NotificationsScreen() {
+ const navigation = useNavigation();
+
return (
- navigation.goBack()} title="Go back home" />
+ navigation.goBack()}>Go back home
);
}
@@ -60,38 +115,510 @@ export default function App() {
}
```
+
+
+
## Opening and closing drawer
To open and close drawer, use the following helpers:
+
+
+
+```js name="Drawer open and close" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function Feed() {
+ const navigation = useNavigation();
+
+ return (
+
+ Feed Screen
+ // codeblock-focus-start
+ navigation.openDrawer()}>Open drawer
+ // codeblock-focus-end
+ navigation.toggleDrawer()}>Toggle drawer
+
+ );
+}
-
+function Notifications() {
+ return (
+
+ Notifications Screen
+
+ );
+}
-```js
-navigation.openDrawer();
-navigation.closeDrawer();
+// codeblock-focus-start
+
+/* content */
+
+// codeblock-focus-end
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ // codeblock-focus-start
+ props.navigation.closeDrawer()}
+ />
+ // codeblock-focus-end
+ props.navigation.toggleDrawer()}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Feed: Feed,
+ Notifications: Notifications,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ return ;
+}
```
+
+
+
+```js name="Drawer open and close" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function Feed() {
+ const navigation = useNavigation();
+
+ return (
+
+ Feed Screen
+ // codeblock-focus-start
+ navigation.openDrawer()}>Open drawer
+ // codeblock-focus-end
+ navigation.toggleDrawer()}>Toggle drawer
+
+ );
+}
+
+function Notifications() {
+ return (
+
+ Notifications Screen
+
+ );
+}
+
+// codeblock-focus-start
+
+/* content */
+
+// codeblock-focus-end
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ // codeblock-focus-start
+ props.navigation.closeDrawer()}
+ />
+ // codeblock-focus-end
+ props.navigation.toggleDrawer()}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+
+function MyDrawer() {
+ return (
+ }
+ >
+
+
+
+ );
+}
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
If you would like to toggle the drawer you call the following:
-
+
+
+
+```js name="Drawer toggle" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function Feed() {
+ const navigation = useNavigation();
-```js
-navigation.toggleDrawer();
+ return (
+
+ Feed Screen
+ navigation.openDrawer()}>Open drawer
+ // codeblock-focus-start
+ navigation.toggleDrawer()}>Toggle drawer
+ // codeblock-focus-end
+
+ );
+}
+
+function Notifications() {
+ return (
+
+ Notifications Screen
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.closeDrawer()}
+ />
+ props.navigation.toggleDrawer()}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Feed: Feed,
+ Notifications: Notifications,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ return ;
+}
```
+
+
+
+```js name="Drawer toggle" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function Feed() {
+ const navigation = useNavigation();
+
+ return (
+
+ Feed Screen
+ navigation.openDrawer()}>Open drawer
+ // codeblock-focus-start
+ navigation.toggleDrawer()}>Toggle drawer
+ // codeblock-focus-end
+
+ );
+}
+
+function Notifications() {
+ return (
+
+ Notifications Screen
+
+ );
+}
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ props.navigation.closeDrawer()}
+ />
+ props.navigation.toggleDrawer()}
+ />
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+
+function MyDrawer() {
+ return (
+ }
+ >
+
+
+
+ );
+}
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
Each of these functions, behind the scenes, are simply dispatching actions:
-
+
+
+
+```js name="Navigation dispatcher" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+ DrawerActions,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function Feed() {
+ const navigation = useNavigation();
+
+ return (
+
+ Feed Screen
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open drawer
+
+ // codeblock-focus-end
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle drawer
+
+
+ );
+}
+
+function Notifications() {
+ return (
+
+ Notifications Screen
+
+ );
+}
+
+// codeblock-focus-start
+
+/* content */
+
+// codeblock-focus-end
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ // codeblock-focus-start
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+ // codeblock-focus-end
+
+ );
+}
+
+const Drawer = createDrawerNavigator({
+ drawerContent: (props) => ,
+ screens: {
+ Feed: Feed,
+ Notifications: Notifications,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
-```js
-navigation.dispatch(DrawerActions.openDrawer());
-navigation.dispatch(DrawerActions.closeDrawer());
-navigation.dispatch(DrawerActions.toggleDrawer());
+export default function App() {
+ return ;
+}
```
+
+
+
+```js name="Navigation dispatcher" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ useNavigation,
+ DrawerActions,
+} from '@react-navigation/native';
+import {
+ createDrawerNavigator,
+ DrawerContentScrollView,
+ DrawerItemList,
+ DrawerItem,
+} from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function Feed() {
+ const navigation = useNavigation();
+
+ return (
+
+ Feed Screen
+ // codeblock-focus-start
+ navigation.dispatch(DrawerActions.openDrawer())}>
+ Open drawer
+
+ // codeblock-focus-end
+ navigation.dispatch(DrawerActions.toggleDrawer())}>
+ Toggle drawer
+
+
+ );
+}
+
+function Notifications() {
+ return (
+
+ Notifications Screen
+
+ );
+}
+// codeblock-focus-start
+
+/* content */
+
+// codeblock-focus-end
+
+function CustomDrawerContent(props) {
+ return (
+
+
+ // codeblock-focus-start
+ props.navigation.dispatch(DrawerActions.closeDrawer())}
+ />
+ props.navigation.dispatch(DrawerActions.toggleDrawer())}
+ />
+ // codeblock-focus-end
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+
+function MyDrawer() {
+ return (
+ }
+ >
+
+
+
+ );
+}
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
If you would like to determine if drawer is open or closed, you can do the following:
-```js
+```js name="Drawer hook"
import { useDrawerStatus } from '@react-navigation/drawer';
// ...
diff --git a/versioned_docs/version-7.x/drawer-layout.md b/versioned_docs/version-7.x/drawer-layout.md
index b332d86feda..0a5d8ddb7d1 100644
--- a/versioned_docs/version-7.x/drawer-layout.md
+++ b/versioned_docs/version-7.x/drawer-layout.md
@@ -4,13 +4,11 @@ title: React Native Drawer Layout
sidebar_label: Drawer Layout
---
-A cross-platform Drawer component for React Native implemented using [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/).
+A cross-platform Drawer component for React Native implemented using [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) on native platforms and CSS transitions on Web.
-
-
-
-
-
+
+
+
This package doesn't integrate with React Navigation. If you want to integrate the drawer layout with React Navigation's navigation system, e.g. want to show screens in the drawer and be able to navigate between them using `navigation.navigate` etc, use [Drawer Navigator](drawer-navigator.md) instead.
@@ -22,50 +20,44 @@ To use this package, open a Terminal in the project root and run:
npm install react-native-drawer-layout
```
-Then, you need to install and configure the libraries that are required by the drawer:
+The library depends on [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) for gestures and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) for animations.
-1. First, install [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/).
+
+
- If you have a Expo managed project, in your project directory, run:
+If you have a Expo managed project, in your project directory, run:
- ```bash
- npx expo install react-native-gesture-handler react-native-reanimated
- ```
-
- If you have a bare React Native project, in your project directory, run:
-
- ```bash npm2yarn
- npm install react-native-gesture-handler react-native-reanimated
- ```
-
- The Drawer supports both Reanimated 1 and the latest version of Reanimated. If you want to use the latest version of Reanimated, make sure to configure it following the [installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started).
+```bash
+npx expo install react-native-gesture-handler react-native-reanimated react-native-worklets
+```
-2. To finalize installation of `react-native-gesture-handler`, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+
+
- ```js
- import 'react-native-gesture-handler';
- ```
+If you have a bare React Native project, in your project directory, run:
- :::warning
+```bash npm2yarn
+npm install react-native-gesture-handler react-native-reanimated react-native-worklets
+```
- If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
+After installation, configure the Reanimated Babel Plugin in your project following the [installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started).
- :::
+
+
-3. If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
+If you're on a Mac and developing for iOS, you also need to install [pods](https://cocoapods.org/) to complete the linking.
```bash
npx pod-install ios
```
-We're done! Now you can build and run the app on your device/simulator.
-
## Quick start
```js
import * as React from 'react';
-import { Button, Text } from 'react-native';
+import { Text } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
+import { Button } from '@react-navigation/elements';
export default function DrawerExample() {
const [open, setOpen] = React.useState(false);
@@ -94,7 +86,7 @@ The package exports a `Drawer` component which is the one you'd use to render th
### `Drawer`
-Component responsible for rendering a drawer with animations and gestures.
+Component is responsible for rendering a drawer sidebar with animations and gestures.
#### Drawer Props
@@ -131,7 +123,7 @@ Type of the drawer. It determines how the drawer looks and animates.
- `slide`: Both the screen and the drawer slide on swipe to reveal the drawer.
- `permanent`: A permanent drawer is shown as a sidebar.
-Defaults to `slide` on iOS and `front` on other platforms.
+Defaults to `front`.
##### `drawerStyle`
@@ -188,11 +180,15 @@ Minimum swipe velocity that should activate opening the drawer. Defaults to `500
This is only supported on iOS and Android.
-##### `gestureHandlerProps`
+#### `configureGestureHandler`
-Props to pass to the underlying pan gesture handler.
+Callback to configure the underlying [gesture from `react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/gesture). It receives the `gesture` object as an argument:
-This is only supported on iOS and Android.
+```js
+configureGestureHandler={({ gesture }) => {
+ return gesture.enableTrackpadTwoFingerGesture(false);
+}}
+```
##### `children`
@@ -200,7 +196,7 @@ Content that the drawer should wrap.
### `useDrawerProgress`
-The `useDrawerProgress` hook returns a Reanimated SharedValue (with modern implementation) or Reanimated Node (with legacy implementation) which represents the progress of the drawer. It can be used to animate the content of the screen.
+The `useDrawerProgress` hook returns a Reanimated `SharedValue` which represents the progress of the drawer. It can be used to animate the content of the screen.
Example with modern implementation:
@@ -227,31 +223,6 @@ function MyComponent() {
}
```
-Example with legacy implementation:
-
-```js
-import { Animated } from 'react-native-reanimated';
-import { useDrawerProgress } from 'react-native-drawer-layout';
-
-// ...
-
-function MyComponent() {
- const progress = useDrawerProgress();
-
- // If you are on react-native-reanimated 1.x, use `Animated.interpolate` instead of `Animated.interpolateNode`
- const translateX = Animated.interpolateNode(progress, {
- inputRange: [0, 1],
- outputRange: [-100, 0],
- });
-
- return (
-
- {/* ... */}
-
- );
-}
-```
-
If you are using class components, you can use the `DrawerProgressContext` to get the progress value.
```js
@@ -269,3 +240,9 @@ class MyComponent extends React.Component {
}
}
```
+
+:::warning
+
+The `useDrawerProgress` hook (or `DrawerProgressContext`) will return a mock value on Web since Reanimated is not used on Web. The mock value can only represent the open state of the drawer (`0` when closed, `1` when open), and not the progress of the drawer.
+
+:::
diff --git a/versioned_docs/version-7.x/drawer-navigator.md b/versioned_docs/version-7.x/drawer-navigator.md
index 3c6a6d63751..9f04798ea15 100644
--- a/versioned_docs/version-7.x/drawer-navigator.md
+++ b/versioned_docs/version-7.x/drawer-navigator.md
@@ -6,11 +6,9 @@ sidebar_label: Drawer
Drawer Navigator renders a navigation drawer on the side of the screen which can be opened and closed via gestures.
-
-
-
-
-
+
+
+
This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use the drawer without React Navigation integration, use the library directly instead.
@@ -19,40 +17,35 @@ This wraps [`react-native-drawer-layout`](drawer-layout.md). If you want to use
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer):
```bash npm2yarn
-npm install @react-navigation/drawer@next
+npm install @react-navigation/drawer
```
-Then, you need to install and configure the libraries that are required by the drawer navigator:
-
-1. First, install [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/).
+The navigator depends on [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) for gestures and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) for animations.
- If you have a Expo managed project, in your project directory, run:
+
+
- ```bash
- npx expo install react-native-gesture-handler react-native-reanimated
- ```
+If you have a Expo managed project, in your project directory, run:
- If you have a bare React Native project, in your project directory, run:
-
- ```bash npm2yarn
- npm install react-native-gesture-handler react-native-reanimated
- ```
-
- The Drawer supports both Reanimated 1 and the latest version of Reanimated. If you want to use the latest version of Reanimated, make sure to configure it following the [installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started).
+```bash
+npx expo install react-native-gesture-handler react-native-reanimated react-native-worklets
+```
-2. To finalize installation of `react-native-gesture-handler`, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
+
+
- ```js
- import 'react-native-gesture-handler';
- ```
+If you have a bare React Native project, in your project directory, run:
- :::warning
+```bash npm2yarn
+npm install react-native-gesture-handler react-native-reanimated react-native-worklets
+```
- If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
+After installation, configure the Reanimated Babel Plugin in your project following the [installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started).
- :::
+
+
-3. If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
+If you're on a Mac and developing for iOS, you also need to install [pods](https://cocoapods.org/) to complete the linking.
```bash
npx pod-install ios
@@ -65,10 +58,14 @@ To use this navigator, import it from `@react-navigation/drawer`:
-```js name="Drawer Navigator" snack version=7
+```js name="Drawer Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
-import { createStaticNavigation, useNavigation } from '@react-navigation/native';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createDrawerNavigator } from '@react-navigation/drawer';
@@ -79,10 +76,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -93,10 +89,7 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Home')}
- />
+ navigation.navigate('Home')}>Go to Home
);
}
@@ -120,10 +113,11 @@ export default function App() {
-```js name="Drawer Navigator" snack version=7
+```js name="Drawer Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createDrawerNavigator } from '@react-navigation/drawer';
@@ -145,10 +139,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -159,10 +152,7 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Home')}
- />
+ navigation.navigate('Home')}>Go to Home
);
}
@@ -179,29 +169,11 @@ export default function App() {
-:::note
-
-For a complete usage guide see [Drawer Navigation](drawer-based-navigation.md).
-
-:::
-
## API Definition
### Props
-The `Drawer.Navigator` component accepts following props:
-
-#### `id`
-
-Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator.
-
-#### `initialRouteName`
-
-The name of the route to render on the first load of the navigator.
-
-#### `screenOptions`
-
-Default options to use for the screens in the navigator.
+In addition to the [common props](navigator.md#configuration) shared by all navigators, the drawer navigator component accepts the following additional props:
#### `backBehavior`
@@ -213,6 +185,7 @@ It supports the following values:
- `initialRoute` - return to initial screen passed in `initialRouteName` prop, if not passed, defaults to the first screen
- `order` - return to screen defined before the focused screen
- `history` - return to last visited screen in the navigator; if the same screen is visited multiple times, the older entries are dropped from the history
+- `fullHistory` - return to last visited screen in the navigator; doesn't drop duplicate entries unlike `history` - this behavior is useful to match how web pages work
- `none` - do not handle back button
#### `defaultStatus`
@@ -225,18 +198,6 @@ When this is set to `open`, the drawer will be open from the initial render. It
Boolean used to indicate whether inactive screens should be detached from the view hierarchy to save memory. This enables integration with [react-native-screens](https://github.com/software-mansion/react-native-screens). Defaults to `true`.
-#### `useLegacyImplementation`
-
-Whether to use the legacy implementation based on Reanimated 1. The new implementation based on Reanimated 2 will perform better, but you need additional configuration and need to use Hermes with Flipper to debug.
-
-This defaults to `true` in the following cases:
-
-- Reanimated 2 is not configured
-- App is connected to Chrome debugger (Reanimated 2 cannot be used with Chrome debugger)
-- App is running on Web
-
-Otherwise, it defaults to `false`
-
#### `drawerContent`
Function that returns React element to render as the content of the drawer, for example, navigation items
@@ -299,42 +260,19 @@ The `DrawerItem` component accepts the following props:
- `labelStyle`: Style object for the label `Text`.
- `style`: Style object for the wrapper `View`.
-The `progress` object can be used to do interesting animations in your `drawerContent`, such as parallax motion of the drawer contents:
-
-
-
-```js
-function CustomDrawerContent(props) {
- const progress = useDrawerProgress();
-
- // If you are on react-native-reanimated 1.x, use `Animated.interpolate` instead of `Animated.interpolateNode`
- const translateX = Animated.interpolateNode(progress, {
- inputRange: [0, 1],
- outputRange: [-100, 0],
- });
-
- return (
-
- {/* ... drawer contents */}
-
- );
-}
-```
-
-The `progress` object is a Reanimated `Node` if you're using Reanimated 1 (see [`useLegacyImplementation`](#uselegacyimplementation)), otherwise a `SharedValue`. It represents the animated position of the drawer (0 is closed; 1 is open).
-
Note that you **cannot** use the `useNavigation` hook inside the `drawerContent` since `useNavigation` is only available inside screens. You get a `navigation` prop for your `drawerContent` which you can use instead:
```js
function CustomDrawerContent({ navigation }) {
return (
{
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
- />
+ >
+ Go somewhere
+
);
}
```
@@ -349,7 +287,7 @@ To use the custom component, we need to pass it in the `drawerContent` prop:
### Options
-The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Drawer.navigator` or `options` prop of `Drawer.Screen`.
+The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Drawer.Navigator` or `options` prop of `Drawer.Screen`.
#### `title`
@@ -371,10 +309,28 @@ Function, that given `{ focused: boolean, color: string, size: number }` returns
Color for the icon and label in the active item in the drawer.
+
+
+```js
+ drawerActiveTintColor: 'green',
+```
+
#### `drawerActiveBackgroundColor`
Background color for the active item in the drawer.
+
+
+```js
+ screenOptions={{
+ drawerActiveTintColor: 'white',
+ drawerActiveBackgroundColor: '#003CB3',
+ drawerLabelStyle: {
+ color: 'white',
+ },
+ }}
+```
+
#### `drawerInactiveTintColor`
Color for the icon and label in the inactive items in the drawer.
@@ -387,10 +343,35 @@ Background color for the inactive items in the drawer.
Style object for the single item, which can contain an icon and/or a label.
+
+
+Example:
+
+```js
+ drawerItemStyle: {
+ backgroundColor: '#9dd3c8',
+ borderColor: 'black',
+ orderWidth: 2,
+ opacity: 0.6,
+ },
+```
+
#### `drawerLabelStyle`
Style object to apply to the `Text` style inside content section which renders a label.
+
+
+Example:
+
+```js
+ drawerLabelStyle: {
+ color: 'black',
+ fontSize: 20,
+ fontFamily: 'Georgia',
+ },
+```
+
#### `drawerContentContainerStyle`
Style object for the content section inside the `ScrollView`.
@@ -403,7 +384,7 @@ Style object for the wrapper view.
Style object for the drawer component. You can pass a custom background color for a drawer or a custom width here.
-
+
```js
+
+
+
- `back`: The drawer is revealed behind the screen on swipe.
+
+
+
+
- `slide`: Both the screen and the drawer slide on swipe to reveal the drawer.
+
+
+
+
- `permanent`: A permanent drawer is shown as a sidebar. Useful for having always visible drawer on larger screens.
Defaults to `slide` on iOS and `front` on other platforms.
@@ -458,6 +451,10 @@ function MyDrawer() {
You can also specify other props such as `drawerStyle` based on screen size to customize the behavior. For example, you can combine it with `defaultStatus="open"` to achieve a master-detail layout:
+
+
+
+
```js
import { useWindowDimensions } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
@@ -490,27 +487,45 @@ When set to `true`, Drawer will hide the OS status bar whenever the drawer is pu
#### `drawerStatusBarAnimation`
-Animation of the statusbar when hiding it. use in combination with `hideStatusBar`.
+Animation of the statusbar when hiding it. use in combination with `drawerHideStatusBarOnOpen`.
+
+This is only supported on iOS. Defaults to `slide`.
Supported values:
- `slide`
+
+
+
+
- `fade`
-- `none`
+
+
+
-This is only supported on iOS. Defaults to `slide`.
+- `none`
#### `overlayColor`
Color overlay to be displayed on top of the content view when drawer gets open. The opacity is animated from `0` to `1` when the drawer opens.
-#### `sceneContainerStyle`
+
+
+
+
+#### `sceneStyle`
Style object for the component wrapping the screen content.
-#### `gestureHandlerProps`
+#### `configureGestureHandler`
+
+Callback to configure the underlying [gesture from `react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/gesture). It receives the `gesture` object as an argument:
-Props to pass to the underlying pan gesture handler.
+```js
+configureGestureHandler: ({ gesture }) => {
+ return gesture.enableTrackpadTwoFingerGesture(false);
+},
+```
This is not supported on Web.
@@ -534,24 +549,22 @@ Minimum swipe distance threshold that should activate opening the drawer.
Whether the keyboard should be dismissed when the swipe gesture begins. Defaults to `'on-drag'`. Set to `'none'` to disable keyboard handling.
-#### `unmountOnBlur`
-
-Whether this screen should be unmounted when navigating away from it. Unmounting a screen resets any local state in the screen as well as state of nested navigators in the screen. Defaults to `false`.
-
-Normally, we don't recommend enabling this prop as users don't expect their navigation history to be lost when switching screens. If you enable this prop, please consider if this will actually provide a better experience for the user.
-
#### `freezeOnBlur`
Boolean indicating whether to prevent inactive screens from re-rendering. Defaults to `false`.
Defaults to `true` when `enableFreeze()` from `react-native-screens` package is run at the top of the application.
-Requires `react-native-screens` version >=3.16.0.
-
Only supported on iOS and Android.
+#### `popToTopOnBlur`
+
+Boolean indicating whether any nested stack should be popped to the top of the stack when navigating away from this drawer screen. Defaults to `false`.
+
+It only works when there is a stack navigator (e.g. [stack navigator](stack-navigator.md) or [native stack navigator](native-stack-navigator.md)) nested under the drawer navigator.
+
### Header related options
-You can find the list of header related options [here](elements.md#header). These [options](screen-options.md) can be specified under `screenOptions` prop of `Drawer.navigator` or `options` prop of `Drawer.Screen`. You don't have to be using `@react-navigation/elements` directly to use these options, they are just documented in that page.
+You can find the list of header related options [here](elements.md#header). These [options](screen-options.md) can be specified under `screenOptions` prop of `Drawer.Navigator` or `options` prop of `Drawer.Screen`. You don't have to be using `@react-navigation/elements` directly to use these options, they are just documented in that page.
In addition to those, the following options are also supported in drawer:
@@ -676,39 +689,140 @@ Navigates to an existing screen in the drawer navigator. The method accepts the
navigation.jumpTo('Profile', { owner: 'Satya' });
```
-## Example
+### Hooks
-
+The drawer navigator exports the following hooks:
-```js
-import { createDrawerNavigator } from '@react-navigation/drawer';
+#### `useDrawerProgress`
-const Drawer = createDrawerNavigator();
+This hook returns the progress of the drawer. It is available in the screen components rendered by the drawer navigator as well as in the [custom drawer content](#drawercontent).
+
+The `progress` object is a `SharedValue` that represents the animated position of the drawer (`0` is closed; `1` is open). It can be used to animate elements based on the animation of the drawer with [Reanimated](https://docs.swmansion.com/react-native-reanimated/):
+
+
+
+
+```js name="Drawer animation progress" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
+import {
+ createDrawerNavigator,
+ useDrawerProgress,
+} from '@react-navigation/drawer';
+import Animated, { useAnimatedStyle } from 'react-native-reanimated';
+
+function HomeScreen() {
+ // highlight-next-line
+ const progress = useDrawerProgress();
+
+ const animatedStyle = useAnimatedStyle(() => ({
+ transform: [{ translateX: progress.value * -100 }],
+ }));
-function MyDrawer() {
return (
-
-
-
+
-
+ );
+}
+// codeblock-focus-end
+
+const MyDrawer = createDrawerNavigator({
+ screens: {
+ Home: HomeScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(MyDrawer);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Drawer animation progress" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
+import {
+ createDrawerNavigator,
+ useDrawerProgress,
+} from '@react-navigation/drawer';
+import Animated, { useAnimatedStyle } from 'react-native-reanimated';
+
+function HomeScreen() {
+ // highlight-next-line
+ const progress = useDrawerProgress();
+
+ const animatedStyle = useAnimatedStyle(() => ({
+ transform: [{ translateX: progress.value * -100 }],
+ }));
+
+ return (
+
+
+
+ );
+}
+// codeblock-focus-end
+
+const Drawer = createDrawerNavigator();
+
+function MyDrawer() {
+ return (
+
+
);
}
+
+export default function App() {
+ return (
+
+
+
+ );
+}
```
-## Checking if the drawer is open
+
+
+
+If you are using class components, you can use the `DrawerProgressContext` to get the progress value.
+
+:::warning
+
+The `useDrawerProgress` hook (or `DrawerProgressContext`) will return a mock value on Web since Reanimated is not used on Web. The mock value can only represent the open state of the drawer (`0` when closed, `1` when open), and not the progress of the drawer.
+
+:::
+
+#### `useDrawerStatus`
You can check if the drawer is open by using the `useDrawerStatus` hook.
@@ -730,7 +844,7 @@ import { getDrawerStatusFromState } from '@react-navigation/drawer';
const isDrawerOpen = getDrawerStatusFromState(navigation.getState()) === 'open';
```
-For class components, you can listen to the `state` event to check if drawer was opened or closed:
+For class components, you can listen to the `state` event to check if the drawer was opened or closed:
```js
class Profile extends React.Component {
diff --git a/versioned_docs/version-7.x/elements.md b/versioned_docs/version-7.x/elements.md
index d8a1d69449e..0e9195a327a 100644
--- a/versioned_docs/version-7.x/elements.md
+++ b/versioned_docs/version-7.x/elements.md
@@ -4,6 +4,9 @@ title: Elements Library
sidebar_label: Elements
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
A component library containing the UI elements and helpers used in React Navigation. It can be useful if you're building your own navigator, or want to reuse a default functionality in your app.
## Installation
@@ -11,18 +14,202 @@ A component library containing the UI elements and helpers used in React Navigat
To use this package, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/elements`](https://github.com/react-navigation/react-navigation/tree/main/packages/elements):
```bash npm2yarn
-npm install @react-navigation/elements@next
+npm install @react-navigation/elements
```
## Components
### `Header`
-A component that can be used as a header. It accepts the following props:
+A component that can be used as a header. This is used by all the navigators by default.
+
+Usage:
+
+```js name="React Navigation Elements Header" snack
+import * as React from 'react';
+import { SafeAreaProviderCompat } from '@react-navigation/elements';
+import { NavigationContainer } from '@react-navigation/native';
+// codeblock-focus-start
+import { Header } from '@react-navigation/elements';
+
+function MyHeader() {
+ return ;
+}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+
+
+ );
+}
+```
+
+To use the header in a navigator, you can use the `header` option in the screen options:
+
+
+
+
+```js name="Header with Native Stack" snack
+import * as React from 'react';
+import { Text, View, Button } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
+import { Header, getHeaderTitle } from '@react-navigation/elements';
+
+// codeblock-focus-end
+function HomeScreen() {
+ return (
+
+ Home Screen
+
+ );
+}
+
+// codeblock-focus-start
+const MyStack = createNativeStackNavigator({
+ screenOptions: {
+ header: ({ options, route, back }) => (
+
+ ),
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(MyStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Header with Native Stack" snack
+import * as React from 'react';
+import { Text, View, Button } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
+import { Header, getHeaderTitle } from '@react-navigation/elements';
+
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+ (
+
+ ),
+ }}
+ >
+
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return (
+
+ Home Screen
+
+ );
+}
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+
+:::note
+
+This doesn't replicate the behavior of the header in stack and native stack navigators as the stack navigator also includes animations, and the native stack navigator header is provided by the native platform.
+
+:::
+
+It accepts the following props:
#### `headerTitle`
-String or a function that returns a React Element to be used by the header. Defaults to scene `title`. When a function is specified, it receives an object containing `allowFontScaling`, `tintColor`, `style` and `children` properties. The `children` property contains the title string.
+String or a function that returns a React Element to be used by the header. Defaults to scene `title`.
+
+When a function is specified, it receives an object containing following properties:
+
+- `allowFontScaling`: Whether it scale to respect Text Size accessibility settings.
+- `tintColor`: Text color of the header title.
+- `style`: Style object for the `Text` component.
+- `children`: The title string (from `title` in `options`).
+
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerTitle: ({ allowFontScaling, tintColor, style, children }) => (
+
+ {children}
+
+ ),
+ },
+ },
+ },
+});
+```
+
+
+
+
+```js
+ (
+
+ {children}
+
+ ),
+ }}
+/>
+```
+
+
+
#### `headerTitleAlign`
@@ -35,11 +222,47 @@ Defaults to `center` on iOS and `left` on Android.
#### `headerTitleAllowFontScaling`
-Whether header title font should scale to respect Text Size accessibility settings. Defaults to false.
+Whether header title font should scale to respect Text Size accessibility settings. Defaults to `false`.
#### `headerLeft`
-Function which returns a React Element to display on the left side of the header. You can use it to implement your custom left button, for example:
+Function which returns a React Element to display on the left side of the header.
+
+It receives an object containing following properties:
+
+- `tintColor`: The color of the icon and label.
+- `pressColor`: The color of the material ripple (Android >= 5.0 only).
+- `pressOpacity`: The opacity of the button when it's pressed (Android < 5.0, and iOS).
+- `displayMode`: How the element displays icon and title. Defaults to `default` on iOS and `minimal` on Android. Possible values:
+ - `default`: Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
+ - `generic`: Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon). iOS >= 14 only, falls back to "default" on older iOS versions.
+ - `minimal`: Always displays only the icon without a title.
+- `href`: The URL to open when the button is pressed on the Web.
+
+You can use it to implement your custom left button, for example:
+
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerLeft: (props) => (
+ {
+ // Do something
+ }}>
+ )
+ }
+ }
+ }
+})
+```
+
+
+
```js
```
+
+
+
#### `headerRight`
Function which returns a React Element to display on the right side of the header.
+It receives an object containing following properties:
+
+- `tintColor`: The color of the icon and label.
+- `pressColor`: The color of the material ripple (Android >= 5.0 only).
+- `pressOpacity`: The opacity of the button when it's pressed (Android < 5.0, and iOS).
+
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerLeft: (props) => (
+ {
+ // Do something
+ }}>
+ )
+ }
+ }
+ }
+})
+```
+
+
+
+
+```js
+ (
+ {
+ // Do something
+ }}
+ />
+ ),
+ }}
+/>
+```
+
+
+
+
+#### `headerSearchBarOptions`
+
+Options for the search bar in the header. When this is specified, the header will contain a button to show a search input.
+
+It can contain the following properties:
+
+- `ref`: Ref to manipulate the search input imperatively. It contains the following methods:
+ - `focus` - focuses the search bar
+ - `blur` - removes focus from the search bar
+ - `setText` - sets the search bar's content to given value
+ - `clearText` - removes any text present in the search bar input field
+ - `cancelSearch` - cancel the search and close the search bar
+- `autoCapitalize`: The auto-capitalization behavior. Possible values: `none`, `words`, `sentences`, `characters`.
+- `autoFocus`: Automatically focus search input on mount.
+- `cancelButtonText`: Text to be used instead of default `Cancel` button text (iOS only).
+- `inputType`: Type of the input. Possible values: `text`, `phone`, `number`, `email`.
+- `onBlur`: Callback that gets called when search input has lost focus.
+- `onChangeText`: Callback that gets called when the text changes.
+- `onClose`: Callback that gets called when search input is closed.
+- `onFocus`: Callback that gets called when search input has received focus.
+- `placeholder`: Text displayed when search input is empty.
+
+```js
+React.useLayoutEffect(() => {
+ navigation.setOptions({
+ headerSearchBarOptions: {
+ placeholder: 'Search',
+ onChangeText: (text) => {
+ // Do something
+ },
+ },
+ });
+}, [navigation]);
+```
+
#### `headerShadowVisible`
Whether to hide the elevation shadow (Android) or the bottom border (iOS) on the header.
@@ -76,11 +386,19 @@ This is a short-hand for the following styles:
}
```
-If the above styles are specified in `headerStyle` along with `headerShadowVisible: false`, then `headerShadowVisible: false` will take precedence.
+If any of the above styles are specified in `headerStyle` along with `headerShadowVisible: false`, then the styles in `headerStyle` will take precedence.
#### `headerStyle`
-Style object for the header. You can specify a custom background color here, for example.
+Style object for the header. You can specify a custom background color here, for example:
+
+```js
+{
+ backgroundColor: 'tomato',
+}
+```
+
+Note that `headerStyle` won't take effect if you are also using [`headerBackground`](#headerbackground). In that case, you should style the element returned from `headerBackground` instead.
#### `headerTitleStyle`
@@ -124,7 +442,7 @@ This is useful if you want to render a semi-transparent header or a blurred back
Note that if you don't want your content to appear under the header, you need to manually add a top margin to your content. React Navigation won't do it automatically.
-To get the height of the header, you can use [`HeaderHeightContext`](#headerheightcontext) with [React's Context API](https://reactjs.org/docs/context.html#contextconsumer) or [`useHeaderHeight`](#useheaderheight).
+To get the height of the header, you can use [`HeaderHeightContext`](#headerheightcontext) with [React's Context API](https://react.dev/reference/react/useContext#contextconsumer) or [`useHeaderHeight`](#useheaderheight).
#### `headerBackground`
@@ -132,25 +450,143 @@ Function which returns a React Element to render as the background of the header
For example, you can use this with `headerTransparent` to render a blur view to create a translucent header.
-
+
+
+
+```js name="Header blur" snack dependencies=expo-blur
+import * as React from 'react';
+import { View, StyleSheet } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+import { BlurView } from 'expo-blur';
-```js
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.goBack()}>Go back
+
+ );
+}
+
+// codeblock-focus-start
+const Stack = createStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerTransparent: true,
+ headerBackground: () => (
+
+ ),
+ },
+ },
+ Profile: ProfileScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
+```
+
+
+
+
+```js name="Header blur" snack dependencies=expo-blur
+import * as React from 'react';
+import { View, StyleSheet } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
import { BlurView } from 'expo-blur';
-// ...
+// codeblock-focus-end
- (
-
- ),
- }}
-/>;
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+function App() {
+ return (
+
+
+ // codeblock-focus-start
+ (
+
+ ),
+ }}
+ />
+ // codeblock-focus-end
+
+
+
+ );
+}
+
+export default App;
```
+
+
+
#### `headerStatusBarHeight`
Extra padding to add at the top of header to account for translucent status bar. By default, it uses the top value from the safe area insets of the device. Pass 0 or a custom value to disable the default behavior, and customize the height.
@@ -177,6 +613,36 @@ Usage:
Hello
```
+### `HeaderButton`
+
+A component used to show a button in header. It can be used for both left and right buttons. It accepts the following props:
+
+- `onPress` - Callback to call when the button is pressed.
+- `href` - The `href` to use for the anchor tag on web.
+- `disabled` - Boolean which controls whether the button is disabled.
+- `accessibilityLabel` - Accessibility label for the button for screen readers.
+- `testID` - ID to locate this button in tests.
+- `tintColor` - Tint color for the header button.
+- `pressColor` - Color for material ripple (Android >= 5.0 only).
+- `pressOpacity` - Opacity when the button is pressed if material ripple isn't supported by the platform.
+- `style` - Style object for the button.
+- `children` - Content to render for the button. Usually the icon.
+
+Usage:
+
+```js
+ console.log('button pressed')}
+>
+
+
+```
+
### `HeaderBackButton`
A component used to show the back button header. It's the default for [`headerLeft`](#headerleft) in the [stack navigator](stack-navigator.md). It accepts the following props:
@@ -188,7 +654,10 @@ A component used to show the back button header. It's the default for [`headerLe
- `tintColor` - Tint color for the header.
- `label` - Label text for the button. Usually the title of the previous screen. By default, this is only shown on iOS.
- `truncatedLabel` - Label text to show when there isn't enough space for the full label.
-- `labelVisible` - Whether the label text is visible. Defaults to `true` on iOS and `false` on Android.
+- `displayMode`: How the back button displays icon and title. Defaults to `default` on iOS and `minimal` on Android. Possible values:
+ - `default`: Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
+ - `generic`: Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon). iOS >= 14 only, falls back to "default" on older iOS versions.
+ - `minimal`: Always displays only the icon without a title.
- `labelStyle` - Style object for the label.
- `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings.
- `onLabelLayout` - Callback to trigger when the size of the label changes.
@@ -220,6 +689,47 @@ A component which provides an abstraction on top of [`Pressable`](https://reactn
- `pressColor` - Color of material ripple on Android when it's pressed
- `pressOpacity` - Opacity when it's pressed if material ripple isn't supported by the platform
+### `Button`
+
+A component that renders a button. In addition to [`PlatformPressable`](#platformpressable)'s props, it accepts following additional props:
+
+- `variant` - Variant of the button. Possible values are:
+ - `tinted` (default)
+ - `plain`
+ - `filled`
+- `color` - Color of the button. Defaults to the [theme](themes.md)'s primary color.
+- `children` - Content to render inside the button.
+
+In addition, the button integrates with React Navigation and accepts the same props as [`useLinkProps`](use-link-props.md#options) hook.
+
+It can be used to navigate between screens by specifying a screen name and params:
+
+```js
+
+ Go to Profile
+
+```
+
+Or as a regular button:
+
+```js
+ console.log('button pressed')}>Press me
+```
+
+### `Label`
+
+The `Label` component is used to render small text. It is used in [Bottom Tab Navigator](bottom-tab-navigator.md) to render the label for each tab.
+
+In addition to the standard [`Text`](https://reactnative.dev/docs/text) props, it accepts the following props:
+
+- `tintColor` - Color of the label. Defaults to the [theme](themes.md)'s text color.
+
+Usage:
+
+```jsx
+Home
+```
+
### `ResourceSavingView`
A component which aids in improving performance for inactive screens by utilizing [`removeClippedSubviews`](https://reactnative.dev/docs/view#removeclippedsubviews). It accepts a `visible` prop to indicate whether a screen should be clipped.
diff --git a/versioned_docs/version-7.x/function-after-focusing-screen.md b/versioned_docs/version-7.x/function-after-focusing-screen.md
index c97f17a3ae7..26528f8eebb 100755
--- a/versioned_docs/version-7.x/function-after-focusing-screen.md
+++ b/versioned_docs/version-7.x/function-after-focusing-screen.md
@@ -1,9 +1,12 @@
---
id: function-after-focusing-screen
title: Call a function when focused screen changes
-sidebar_label: Call a function when focused screen changes
+sidebar_label: Call a function on focus
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
In this guide we will call a function or render something on screen focusing. This is useful for making additional API calls when a user revisits a particular screen in a Tab Navigator, or to track user events as they tap around our app.
There are multiple approaches available to us:
@@ -20,15 +23,77 @@ With this approach, we will only be able to call an action when the screen focus
Example:
-
+
+
+
+```js name="Focus event listener" snack
+// codeblock-focus-start
+import * as React from 'react';
+import { View } from 'react-native';
+
+// codeblock-focus-end
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+// codeblock-focus-start
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('focus', () => {
+ alert('Screen is focused');
+ // The screen is focused
+ // Call any action
+ });
+
+ // Return the function to unsubscribe from the event so it gets removed on unmount
+ return unsubscribe;
+ }, [navigation]);
+
+ return ;
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const MyTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
-```js
+const Navigation = createStaticNavigation(MyTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Focus event listener" snack
+// codeblock-focus-start
import * as React from 'react';
import { View } from 'react-native';
-function ProfileScreen({ navigation }) {
+// codeblock-focus-end
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+// codeblock-focus-start
+function ProfileScreen() {
+ const navigation = useNavigation();
+
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
+ alert('Screen is focused');
// The screen is focused
// Call any action
});
@@ -39,61 +104,229 @@ function ProfileScreen({ navigation }) {
return ;
}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
See the [navigation events guide](navigation-events.md) for more details on the event listener API.
In most cases, it's recommended to use the `useFocusEffect` hook instead of adding the listener manually. See below for details.
## Triggering an action with the `useFocusEffect` hook
-React Navigation provides a [hook](https://reactjs.org/docs/hooks-intro.html) that runs an effect when the screen comes into focus and cleans it up when it goes out of focus. This is useful for cases such as adding event listeners, for fetching data with an API call when a screen becomes focused, or any other action that needs to happen once the screen comes into view.
+React Navigation provides a [hook](use-focus-effect.md) that runs an effect when the screen comes into focus and cleans it up when it goes out of focus. This is useful for cases such as adding event listeners, for fetching data with an API call when a screen becomes focused, or any other action that needs to happen once the screen comes into view.
This is particularly handy when we are trying to stop something when the page is unfocused, like stopping a video or audio file from playing, or stopping the tracking of a user's location.
-
+
+
+
+```js name="useFocusEffect hook" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import {
+ useFocusEffect,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+// codeblock-focus-start
+function ProfileScreen() {
+ useFocusEffect(
+ React.useCallback(() => {
+ alert('Screen was focused');
+ // Do something when the screen is focused
+ return () => {
+ alert('Screen was unfocused');
+ // Do something when the screen is unfocused
+ // Useful for cleanup functions
+ };
+ }, [])
+ );
+
+ return ;
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const MyTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+const Navigation = createStaticNavigation(MyTabs);
+
+export default function App() {
+ return ;
+}
+```
-```js
-import { useFocusEffect } from '@react-navigation/native';
+
+
-function Profile({ userId }) {
- const [user, setUser] = React.useState(null);
+```js name="useFocusEffect hook" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer, useFocusEffect } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+// codeblock-focus-start
+function ProfileScreen() {
useFocusEffect(
React.useCallback(() => {
- const unsubscribe = API.subscribe(userId, user => setUser(data));
-
- return () => unsubscribe();
- }, [userId])
+ alert('Screen was focused');
+ // Do something when the screen is focused
+ return () => {
+ alert('Screen was unfocused');
+ // Do something when the screen is unfocused
+ // Useful for cleanup functions
+ };
+ }, [])
);
- return ;
+ return ;
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
See the [`useFocusEffect`](https://reactnavigation.org/docs/use-focus-effect/) documentation for more details.
## Re-rendering screen with the `useIsFocused` hook
-React Navigation provides a [hook](https://reactjs.org/docs/hooks-intro.html) that returns a boolean indicating whether the screen is focused or not.
+React Navigation provides a [hook](use-is-focused.md) that returns a boolean indicating whether the screen is focused or not.
The hook will return `true` when the screen is focused and `false` when our component is no longer focused. This enables us to render something conditionally based on whether the user is on the screen or not.
The `useIsFocused` hook will cause our component to re-render when we focus and unfocus a screen. Using this hook component may introduce unnecessary component re-renders as a screen comes in and out of focus. This could cause issues depending on the type of action we're calling on focusing. Hence we recommend to use this hook only if you need to trigger a re-render. For side-effects such as subscribing to events or fetching data, use the methods described above.
-
+
+
+
+```js name="useIsFocused hook" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { useIsFocused, createStaticNavigation } from '@react-navigation/native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+
+// codeblock-focus-start
+function ProfileScreen() {
+ // codeblock-focus-end
+ // This hook returns `true` if the screen is focused, `false` otherwise
+ // codeblock-focus-start
+ const isFocused = useIsFocused();
+
+ return (
+
+ {isFocused ? 'focused' : 'unfocused'}
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const MyTabs = createMaterialTopTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
-```js
+const Navigation = createStaticNavigation(MyTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="useIsFocused hook" snack
import * as React from 'react';
-import { Text } from 'react-native';
-import { useIsFocused } from '@react-navigation/native';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useIsFocused } from '@react-navigation/native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
-function Profile() {
+// codeblock-focus-start
+function ProfileScreen() {
+ // codeblock-focus-end
// This hook returns `true` if the screen is focused, `false` otherwise
+ // codeblock-focus-start
const isFocused = useIsFocused();
- return {isFocused ? 'focused' : 'unfocused'} ;
+ return (
+
+ {isFocused ? 'focused' : 'unfocused'}
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createMaterialTopTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
This example is also documented in the [`useIsFocused` API documentation](use-is-focused.md).
diff --git a/versioned_docs/version-7.x/getting-started.md b/versioned_docs/version-7.x/getting-started.md
index ee0906636a4..2e7d1b8dc5b 100755
--- a/versioned_docs/version-7.x/getting-started.md
+++ b/versioned_docs/version-7.x/getting-started.md
@@ -15,30 +15,47 @@ If you're already familiar with JavaScript, React and React Native, then you'll
Here are some resources to help you out:
-1. [React Native Express](https://www.reactnative.express) (Sections 1 to 4)
-2. [Main Concepts of React](https://react.dev/learn)
-3. [React Hooks](https://react.dev/reference/react)
-4. [React Context](https://react.dev/learn/passing-data-deeply-with-context) (Advanced)
+1. [Main Concepts of React](https://react.dev/learn)
+2. [Getting started with React Native](https://reactnative.dev/docs/getting-started)
+3. [React Hooks](https://react.dev/reference/react/hooks)
+4. [React Context](https://react.dev/learn/passing-data-deeply-with-context)
## Minimum requirements
- `react-native` >= 0.72.0
-- `expo` >= 49 (if you use Expo)
+- `expo` >= 52 (if you use [Expo Go](https://expo.dev/go))
- `typescript` >= 5.0.0 (if you use TypeScript)
+## Starter template
+
+If you're starting a new project, you can use the [React Navigation template](https://github.com/react-navigation/template) to quickly set up a new project with [Static configuration](#static-configuration):
+
+```bash
+npx create-expo-app@latest --template react-navigation/template
+```
+
+See the project's `README.md` for more information on how to get started.
+
+If you created a new project using the template, you can skip the installation steps below and move on to ["Hello React Navigation"](hello-react-navigation.md?config=static).
+
+Otherwise, you can follow the instructions below to install React Navigation into your existing project.
+
## Installation
-Install the required packages in your React Native project:
+The `@react-navigation/native` package contains the core functionality of React Navigation.
+
+In your project directory, run:
```bash npm2yarn
-npm install @react-navigation/native@next
+npm install @react-navigation/native
```
-React Navigation is made up of some core utilities and those are then used by navigators to create the navigation structure in your app. Don't worry too much about this for now, it'll become clear soon enough! To frontload the installation work, let's also install and configure dependencies used by most navigators, then we can move forward with starting to write some code.
+### Installing dependencies
-The libraries we will install now are [`react-native-screens`](https://github.com/software-mansion/react-native-screens) and [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context). If you already have these libraries installed and at the latest version, you are done here! Otherwise, read on.
+Let's also install and configure dependencies used by most navigators. The libraries we will install now are [`react-native-screens`](https://github.com/software-mansion/react-native-screens) and [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context).
-### Installing dependencies into an Expo managed project
+
+
In your project directory, run:
@@ -46,11 +63,10 @@ In your project directory, run:
npx expo install react-native-screens react-native-safe-area-context
```
-This will install versions of these libraries that are compatible.
+This will install versions of these libraries that are compatible with your Expo SDK version.
-You can now continue to ["Hello React Navigation"](hello-react-navigation.md) to start writing some code.
-
-### Installing dependencies into a bare React Native project
+
+
In your project directory, run:
@@ -58,52 +74,61 @@ In your project directory, run:
npm install react-native-screens react-native-safe-area-context
```
-:::note
-
-You might get warnings related to peer dependencies after installation. They are usually caused by incorrect version ranges specified in some packages. You can safely ignore most warnings as long as your app builds.
-
-:::
-
-From React Native 0.60 and higher, [linking is automatic](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md). So you **don't need to run** `react-native link`.
-
If you're on a Mac and developing for iOS, you need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
```bash
npx pod-install ios
```
-`react-native-screens` package requires one additional configuration step to properly
-work on Android devices. Edit `MainActivity.kt` or `MainActivity.java` file which is located under `android/app/src/main/java//`.
+#### Configuring `react-native-screens` on Android
+
+[`react-native-screens`](https://github.com/software-mansion/react-native-screens) requires one additional configuration to properly work on Android.
-Add the highlighted code to the body of `MainActivity` class:
+Edit `MainActivity.kt` or `MainActivity.java` file under `android/app/src/main/java//`, and add the highlighted code to the body of `MainActivity` class:
```kotlin
+// highlight-start
+import android.os.Bundle
+import com.swmansion.rnscreens.fragment.restoration.RNScreensFragmentFactory
+// highlight-end
+
+// ...
+
class MainActivity: ReactActivity() {
// ...
- // highlight-start
override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(null)
+ // highlight-start
+ supportFragmentManager.fragmentFactory = RNScreensFragmentFactory()
+ super.onCreate(savedInstanceState)
+ // highlight-end
}
- // highlight-end
// ...
}
```
-
-
+
+
```java
+// highlight-start
+import android.os.Bundle;
+import com.swmansion.rnscreens.fragment.restoration.RNScreensFragmentFactory;
+// highlight-end
+
+// ...
+
public class MainActivity extends ReactActivity {
// ...
- // highlight-start
@Override
protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(null);
+ // highlight-start
+ getSupportFragmentManager().setFragmentFactory(new RNScreensFragmentFactory());
+ super.onCreate(savedInstanceState);
+ // highlight-end
}
- // highlight-end
// ...
}
```
@@ -111,19 +136,25 @@ public class MainActivity extends ReactActivity {
-and make sure to add the following import statement at the top of this file below your package statement:
+This change is required to avoid crashes related to View state being not persisted consistently across Activity restarts.
-```java
-import android.os.Bundle;
-```
+#### Opting-out of predictive back on Android
-This change is required to avoid crashes related to View state being not persisted consistently across Activity restarts.
+React Navigation doesn't yet support Android's predictive back gesture. Disabling it is necessary for the system back gesture to work properly with React Navigation.
-:::info
+To opt out, in `AndroidManifest.xml`, in the `` tag (or `` tag to opt-out at activity level), set the `android:enableOnBackInvokedCallback` flag to `false`:
-When you use a navigator (such as stack navigator), you'll need to follow the installation instructions of that navigator for any additional dependencies. If you're getting an error "Unable to resolve module", you need to install that module in your project.
+```xml
+
+
+
+```
-:::
+
+
## Setting up React Navigation
@@ -131,36 +162,24 @@ Once you've installed and configured the dependencies, you can move on to settin
When using React Navigation, you configure [**navigators**](glossary-of-terms.md#navigator) in your app. Navigators handle the transition between screens in your app and provide UI such as header, tab bar etc.
-There are 2 primary ways to configure the navigators:
-
-### Static configuration
-
-The static configuration API has reduced boilerplate and simplifies things such as TypeScript types and deep linking. If you're starting a new project or are new to React Navigation, this is the **recommended way** to set up your app. If you need more flexibility in the future, you can always mix and match with the dynamic configuration.
+:::info
-Continue to ["Hello React Navigation"](hello-react-navigation.md?config=static) to start writing some code with the static API.
+When you use a navigator (such as stack navigator), you'll need to follow the installation instructions of that navigator for any additional dependencies.
-### Dynamic configuration
+:::
-The dynamic configuration allows for more flexibility but requires more boilerplate and configuration (e.g. for deep links, typescript etc.).
+There are 2 primary ways to configure the navigators:
-To get started with dynamic configuration, first, we need to wrap your app in `NavigationContainer`. Usually, you'd do this in your entry file, such as `index.js` or `App.js`:
+### Static configuration
-```js
-import * as React from 'react';
-// highlight-next-line
-import { NavigationContainer } from '@react-navigation/native';
+The static configuration API lets you write your configuration in an object, and is defined statically, though some aspects of the configuration can still can be changed dynamically. This has reduced boilerplate and simplifies things such as TypeScript types and deep linking.
-export default function App() {
- return (
- {/* Rest of your app code */}
- );
-}
-```
+If you're starting a new project or are new to React Navigation, this is the **recommended way** to set up your app. If you need more flexibility in the future, you can always mix and match with the dynamic configuration.
-:::warning
+Continue to ["Hello React Navigation"](hello-react-navigation.md?config=static) to start writing some code with the static API.
-In a typical React Native app, the `NavigationContainer` should be only used once in your app at the root. You shouldn't nest multiple `NavigationContainer`s unless you have a specific use case for them.
+### Dynamic configuration
-:::
+The dynamic configuration API lets you write your configuration in React components, and can change at runtime based on state or props. This allows for more flexibility but requires significantly more boilerplate and configuration for Typescript types, deep linking etc.
Continue to ["Hello React Navigation"](hello-react-navigation.md?config=dynamic) to start writing some code with the dynamic API.
diff --git a/versioned_docs/version-7.x/group.md b/versioned_docs/version-7.x/group.md
index 95dae48a557..4a7b6583abb 100644
--- a/versioned_docs/version-7.x/group.md
+++ b/versioned_docs/version-7.x/group.md
@@ -4,75 +4,332 @@ title: Group
sidebar_label: Group
---
-`Group` components are used to group several [screens](screen.md) inside a navigator.
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
-A `Group` is returned from a `createXNavigator` function:
+A group contains several [screens](screen.md) inside a navigator for organizational purposes. They can also be used to apply the same options such as header styles to a group of screens, or to define a common layout etc.
-```js
-const Stack = createStackNavigator(); // Stack contains Screen & Navigator properties
+
+
+
+Groups can be defined using the `groups` property in the navigator configuration:
+
+```js name="Stack groups" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+ navigation.navigate('Search')}>
+ Go to Search
+
+
+ );
+}
+
+function EmptyScreen() {
+ return ;
+}
+
+// codeblock-focus-start
+const MyStack = createNativeStackNavigator({
+ groups: {
+ App: {
+ screenOptions: {
+ headerStyle: {
+ backgroundColor: '#FFB6C1',
+ },
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: EmptyScreen,
+ },
+ },
+ Modal: {
+ screenOptions: {
+ presentation: 'modal',
+ },
+ screens: {
+ Search: EmptyScreen,
+ Share: EmptyScreen,
+ },
+ },
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
```
-After creating the navigator, it can be used as children of the `Navigator` component:
+The keys of the `groups` object (e.g. `Guest`, `User`) are used as the [`navigationKey`](#navigation-key) for the group. You can use any string as the key.
-
+
+
-```js
-
-
-
-
-
-
-
-
-
-
+A `Group` component is returned from a `createXNavigator` function. After creating the navigator, it can be used as children of the `Navigator` component:
+
+```js name="Stack groups" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+
+const Stack = createNativeStackNavigator();
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+ navigation.navigate('Search')}>
+ Go to Search
+
+
+ );
+}
+
+function EmptyScreen() {
+ return ;
+}
+
+export default function App() {
+ return (
+
+ // codeblock-focus-start
+
+
+
+
+
+
+
+
+
+
+ // codeblock-focus-end
+
+ );
+}
```
It's also possible to nest `Group` components inside other `Group` components.
-## Props
+
+
+
+## Configuration
-### `screenOptions`
+### Screen options
Options to configure how the screens inside the group get presented in the navigator. It accepts either an object or a function returning an object:
+
+
+
```js
+const MyStack = createNativeStackNavigator({
+ groups: {
+ Modal: {
+ // highlight-start
+ screenOptions: {
+ presentation: 'modal',
+ },
+ // highlight-end
+ screens: {
+ /* screens */
+ },
+ },
+ },
+});
+```
+
+
+
+
+```jsx
{/* screens */}
```
+
+
+
When you pass a function, it'll receive the [`route`](route-object.md) and [`navigation`](navigation-object.md):
+
+
+
```js
+const MyStack = createNativeStackNavigator({
+ groups: {
+ Modal: {
+ // highlight-start
+ screenOptions: ({ route, navigation }) => ({
+ title: route.params.title,
+ }),
+ // highlight-end
+ screens: {
+ /* screens */
+ },
+ },
+ },
+});
+```
+
+
+
+
+```jsx
({
title: route.params.title,
})}
+ // highlight-end
>
{/* screens */}
```
+
+
+
These options are merged with the `options` specified in the individual screens, and the screen's options will take precedence over the group's options.
See [Options for screens](screen-options.md) for more details and examples.
-### `navigationKey`
+### Screen layout
+
+A screen layout is a wrapper around each screen in the group. It makes it easier to provide things such as an error boundary and suspense fallback for all screens in the group, or wrap each screen with additional UI.
-Optional key for a group of screens screen. If the key changes, all existing screens in this group will be removed (if used in a stack navigator) or reset (if used in a tab or drawer navigator):
+It takes a function that returns a React element:
+
+
+
```js
-
+const MyStack = createNativeStackNavigator({
+ groups: {
+ Modal: {
+ // highlight-start
+ screenLayout: ({ children }) => (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ ),
+ // highlight-end
+ screens: {
+ /* screens */
+ },
+ },
+ },
+});
+```
+
+
+
+
+```jsx
+ (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ )}
+ // highlight-end
+>
{/* screens */}
```
-This is similar to the [`navigationKey`](screen.md#navigationkey) prop on `Screen`, but applies to a group of screens.
+
+
+
+### Navigation key
+
+Optional key for a group of screens. If the key changes, all existing screens in this group will be removed (if used in a stack navigator) or reset (if used in a tab or drawer navigator):
+
+
+
+
+The name of the group is used as the `navigationKey`:
+
+```js
+const MyStack = createNativeStackNavigator({
+ groups: {
+ // highlight-next-line
+ User: {
+ screens: {
+ /* screens */
+ },
+ },
+ // highlight-next-line
+ Guest: {
+ screens: {
+ /* screens */
+ },
+ },
+ },
+});
+```
+
+This means if a screen is defined in 2 groups and the groups use the [`if`](static-configuration.md#if) property, the screen will remount if the condition changes resulting in one group being removed and the other group being used.
+
+
+
+
+```jsx
+
+ {/* screens */}
+
+```
+
+
+
+
+This is similar to the [`navigationKey`](screen.md#navigation-key) prop for screens, but applies to a group of screens.
diff --git a/versioned_docs/version-7.x/handling-safe-area.md b/versioned_docs/version-7.x/handling-safe-area.md
index 31c00f09099..225bfa87c1d 100755
--- a/versioned_docs/version-7.x/handling-safe-area.md
+++ b/versioned_docs/version-7.x/handling-safe-area.md
@@ -4,6 +4,9 @@ title: Supporting safe areas
sidebar_label: Supporting safe areas
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
By default, React Navigation tries to ensure that the elements of the navigators display correctly on devices with notches (e.g. iPhone X) and UI elements which may overlap the app content. Such items include:
- Physical notches
@@ -25,7 +28,7 @@ While React Native exports a `SafeAreaView` component, this component only suppo
:::warning
-The `react-native-safe-area-context` library also exports a `SafeAreaView` component. While it works on Android, it also has the same issues related to jumpy behavior when animating. So we recommend always using the `useSafeAreaInsets` hook instead and avoid using the `SafeAreaView` component.
+The `react-native-safe-area-context` library also exports a `SafeAreaView` component. While it works on Android, it also has the same issues with jumpy behavior on vertical animations. In addition, the `SafeAreaView` component and `useSafeAreaInsets` hook can update at different times, resulting in flickering when using them together. So we recommend always using the `useSafeAreaInsets` hook instead and avoid using the `SafeAreaView` component for consistent behavior.
:::
@@ -39,9 +42,68 @@ React Navigation handles safe area in the default header. However, if you're usi
For example, if I render nothing for the `header` or `tabBar`, nothing renders
-
+
+
-```jsx
+```js name="Hidden components" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function Demo() {
+ return (
+
+ This is top text.
+ This is bottom text.
+
+ );
+}
+
+// codeblock-focus-start
+const MyTabs = createBottomTabNavigator({
+ initialRouteName: 'Analytics',
+ // highlight-start
+ tabBar: () => null,
+ screenOptions: {
+ headerShown: false,
+ },
+ // highlight-end
+ screens: {
+ Analytics: Demo,
+ Profile: Demo,
+ },
+});
+
+const RootStack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ // highlight-start
+ screenOptions: {
+ headerShown: false,
+ },
+ // highlight-end
+ screens: {
+ Home: MyTabs,
+ Settings: Demo,
+ },
+});
+
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Hidden components" snack
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
@@ -71,11 +133,11 @@ export default function App() {
{() => (
null}
screenOptions={{ headerShown: false }}
>
-
+
)}
@@ -88,18 +150,28 @@ export default function App() {
}
```
+
+
+

To fix this issue you can apply safe area insets on your content. This can be achieved using the `useSafeAreaInsets` hook from the `react-native-safe-area-context` library:
-
+
+
-```jsx
+```js name="Safe area example" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
import {
SafeAreaProvider,
useSafeAreaInsets,
} from 'react-native-safe-area-context';
+// codeblock-focus-start
function Demo() {
const insets = useSafeAreaInsets();
@@ -109,8 +181,80 @@ function Demo() {
flex: 1,
justifyContent: 'space-between',
alignItems: 'center',
+ paddingTop: insets.top,
+ paddingBottom: insets.bottom,
+ paddingLeft: insets.left,
+ paddingRight: insets.right,
+ }}
+ >
+ This is top text.
+ This is bottom text.
+
+ );
+}
+// codeblock-focus-end
+
+const MyTabs = createBottomTabNavigator({
+ initialRouteName: 'Analytics',
+ tabBar: () => null,
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Analytics: Demo,
+ Profile: Demo,
+ },
+});
+
+const RootStack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Home: MyTabs,
+ Settings: Demo,
+ },
+});
+
+// codeblock-focus-start
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return (
+
+
+
+ );
+}
+// codeblock-focus-end
+```
- // Paddings to handle safe area
+
+
+
+```js name="Safe area example" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import {
+ SafeAreaProvider,
+ useSafeAreaInsets,
+} from 'react-native-safe-area-context';
+
+// codeblock-focus-start
+function Demo() {
+ const insets = useSafeAreaInsets();
+
+ return (
+
);
}
+// codeblock-focus-end
+const Stack = createNativeStackNavigator();
+const Tab = createBottomTabNavigator();
+
+// codeblock-focus-start
export default function App() {
return (
- {/*(...) */}
+
+ {/*(...) */}
+ // codeblock-focus-end
+
+
+ {() => (
+ null}
+ screenOptions={{ headerShown: false }}
+ >
+
+
+
+ )}
+
+
+
+ // codeblock-focus-start
+
);
}
+// codeblock-focus-end
```
+
+
+
Make sure to wrap your app in `SafeAreaProvider` as per the instructions [here](https://github.com/th3rdwave/react-native-safe-area-context#usage).

@@ -152,14 +327,95 @@ To fix this you can, once again, apply safe area insets to your content. This wi
In some cases you might need more control over which paddings are applied. For example, you can only apply the top and the bottom padding by changing the `style` object:
-
+
+
-```jsx
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
+```js name="useSafeAreaInsets hook" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
+import {
+ SafeAreaProvider,
+ useSafeAreaInsets,
+} from 'react-native-safe-area-context';
function Demo() {
const insets = useSafeAreaInsets();
+ return (
+
+ This is top text.
+ This is bottom text.
+
+ );
+}
+// codeblock-focus-end
+
+const MyTabs = createBottomTabNavigator({
+ initialRouteName: 'Analytics',
+ tabBar: () => null,
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Analytics: Demo,
+ Profile: Demo,
+ },
+});
+
+const RootStack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Home: MyTabs,
+ Settings: Demo,
+ },
+});
+
+// codeblock-focus-start
+
+const Navigation = createStaticNavigation(RootStack);
+export default function App() {
+ return (
+
+
+
+ );
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="useSafeAreaInsets hook" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createStackNavigator } from '@react-navigation/stack';
+// codeblock-focus-start
+import {
+ SafeAreaProvider,
+ useSafeAreaInsets,
+} from 'react-native-safe-area-context';
+
+function Demo() {
+ const insets = useSafeAreaInsets();
return (
);
}
+// codeblock-focus-end
+
+const Stack = createStackNavigator();
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+ {() => (
+ null}
+ screenOptions={{ headerShown: false }}
+ >
+
+
+
+ )}
+
+
+
+
+
+
+ );
+}
```
+
+
+
Similarly, you could apply these paddings in `contentContainerStyle` of `FlatList` to have the content avoid the safe areas, but still show them under the statusbar and navigation bar when scrolling.
## Summary
-- Use `useSafeAreaInsets` hook from `react-native-safe-area-context` instead of `SafeAreaView` component
+- Use [`useSafeAreaInsets`](https://appandflow.github.io/react-native-safe-area-context/api/use-safe-area-insets) hook from `react-native-safe-area-context` instead of [`SafeAreaView`](https://reactnative.dev/docs/safeareaview) component
- Don't wrap your whole app in `SafeAreaView`, instead apply the styles to content inside your screens
- Apply only specific insets using the `useSafeAreaInsets` hook for more control
diff --git a/versioned_docs/version-7.x/header-buttons.md b/versioned_docs/version-7.x/header-buttons.md
index b670e891082..8861a6120b4 100755
--- a/versioned_docs/version-7.x/header-buttons.md
+++ b/versioned_docs/version-7.x/header-buttons.md
@@ -16,11 +16,12 @@ The most common way to interact with a header is by tapping on a button either t
-```js name="Header button" snack version=7
+```js name="Header button" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
return (
@@ -38,7 +39,7 @@ const MyStack = createNativeStackNavigator({
options: {
// highlight-start
headerRight: () => (
- alert('This is a button!')} title="Info" />
+ alert('This is a button!')}>Info
),
// highlight-end
},
@@ -57,11 +58,12 @@ export default function App() {
-```js name="Header button" snack version=7
+```js name="Header button" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
return (
@@ -83,7 +85,7 @@ function MyStack() {
options={{
// highlight-start
headerRight: () => (
- alert('This is a button!')} title="Info" />
+ alert('This is a button!')}>Info
),
// highlight-end
}}
@@ -105,6 +107,8 @@ export default function App() {
+
+
When we define our button this way, the `this` variable in `options` is _not_ the `HomeScreen` instance, so you can't call `setState` or any instance methods on it. This is pretty important because it's common to want the buttons in your header to interact with the screen that the header belongs to. So, we will look how to do this next.
:::tip
@@ -120,14 +124,15 @@ In some cases, components in the header need to interact with the screen compone
-```js name="Header button" snack version=7
+```js name="Header button" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
function HomeScreen() {
@@ -140,7 +145,7 @@ function HomeScreen() {
// highlight-start
navigation.setOptions({
headerRight: () => (
- setCount((c) => c + 1)} title="Update count" />
+ setCount((c) => c + 1)}>Update count
),
});
// highlight-end
@@ -156,7 +161,7 @@ const MyStack = createNativeStackNavigator({
options: {
// Add a placeholder button without the `onPress` to avoid flicker
// highlight-next-line
- headerRight: () => ,
+ headerRight: () => Update count ,
},
},
},
@@ -173,11 +178,12 @@ export default function App() {
-```js name="Header button" snack version=7
+```js name="Header button" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
const Stack = createNativeStackNavigator();
@@ -192,7 +198,7 @@ function HomeScreen() {
// highlight-start
navigation.setOptions({
headerRight: () => (
- setCount((c) => c + 1)} title="Update count" />
+ setCount((c) => c + 1)}>Update count
),
});
// highlight-end
@@ -210,7 +216,7 @@ function MyStack() {
options={{
// Add a placeholder button without the `onPress` to avoid flicker
// highlight-next-line
- headerRight: () => ,
+ headerRight: () => Update count ,
}}
/>
@@ -230,6 +236,10 @@ export default function App() {
+
+
+
+
Here we update the `headerRight` with a button with `onPress` handler that has access to the component's state and can update it.
## Customizing the back button
@@ -240,6 +250,45 @@ You can change the label behavior with `headerBackTitle` and style it with `head
To customize the back button image, you can use `headerBackImageSource` ([read more](native-stack-navigator.md#headerbackimagesource)).
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerBackTitle: 'Custom Back',
+ headerBackTitleStyle: { fontSize: 30 },
+ },
+ },
+ },
+});
+```
+
+
+
+
+```js
+
+
+
+
+```
+
+
+
+
+
+
## Overriding the back button
The back button will be rendered automatically in a stack navigator whenever it is possible for the user to go back from their current screen — in other words, the back button will be rendered whenever there is more than one screen in the stack.
@@ -248,6 +297,6 @@ Generally, this is what you want. But it's possible that in some circumstances t
## Summary
-- You can set buttons in the header through the `headerLeft` and `headerRight` properties in `options`.
-- The back button is fully customizable with `headerLeft`, but if you just want to change the title or image, there are other `options` for that — `headerBackTitle`, `headerBackTitleStyle`, and `headerBackImageSource`.
-- You can use a callback for the options prop to access `navigation` and `route` objects.
+- You can set buttons in the header through the [`headerLeft`](elements.md#headerleft) and [`headerRight`](elements.md#headerright) properties in [`options`](screen-options.md).
+- The back button is fully customizable with `headerLeft`, but if you only want to change the title or image, there are other `options` for that — [`headerBackTitle`](native-stack-navigator.md#headerbacktitle), [`headerBackTitleStyle`](native-stack-navigator.md#headerbacktitlestyle), and [`headerBackImageSource`](native-stack-navigator.md#headerbackimagesource).
+- You can use a callback for the options prop to access [`navigation`](navigation-object.md) and [`route`](route-object.md) objects.
diff --git a/versioned_docs/version-7.x/headers.md b/versioned_docs/version-7.x/headers.md
index e3797851e7e..04f18811603 100755
--- a/versioned_docs/version-7.x/headers.md
+++ b/versioned_docs/version-7.x/headers.md
@@ -16,7 +16,7 @@ Each screen has `options` which is either an object or a function that returns a
-```js name="Setting header title" snack version=7
+```js name="Setting header title" snack
import * as React from 'react';
import { Text, View } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
@@ -55,7 +55,7 @@ export default function App() {
-```js name="Setting header title" snack version=7
+```js name="Setting header title" snack
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
@@ -101,6 +101,8 @@ export default function App() {
+
+
## Using params in the title
In order to use params in the title, we need to make `options` for the screen a function that returns a configuration object. If we make `options` a function then React Navigation will call it with an object containing `{ navigation, route }` - in this case, all we care about is `route`, which is the same object that is passed to your screen props as `route` prop. You may recall that we can get the params through `route.params`, and so we do this below to extract a param and use it as a title.
@@ -108,14 +110,15 @@ In order to use params in the title, we need to make `options` for the screen a
-```js name="Using params in the title" snack version=7
+```js name="Using params in the title" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -123,13 +126,14 @@ function HomeScreen() {
return (
navigation.navigate('Profile', {
name: 'Jane',
})
}
- />
+ >
+ Go to Profile
+
);
}
@@ -173,11 +177,12 @@ export default function App() {
-```js name="Using params in the title" snack version=7
+```js name="Using params in the title" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -185,13 +190,14 @@ function HomeScreen() {
return (
navigation.navigate('Profile', {
name: 'Jane',
})
}
- />
+ >
+ Go to Profile
+
);
}
@@ -252,14 +258,15 @@ We only needed the `route` object in the above example but you may in some cases
It's often necessary to update the `options` configuration for the active screen from the mounted screen component itself. We can do this using `navigation.setOptions`
-```js name="Updating options" snack version=7
+```js name="Updating options" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -269,12 +276,13 @@ function HomeScreen() {
Home Screen
// codeblock-focus-start
// highlight-next-line
navigation.setOptions({ title: 'Updated!' })
}
- />
+ >
+ Update the title
+
// codeblock-focus-end
);
@@ -309,7 +317,7 @@ There are three key properties to use when customizing the style of your header:
-```js name="Header styles" snack version=7
+```js name="Header styles" snack
import * as React from 'react';
import { Text, View } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
@@ -355,9 +363,9 @@ export default function App() {
-```js name="Header styles" snack version=7
+```js name="Header styles" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
@@ -422,14 +430,15 @@ It is common to want to configure the header in a similar way across many screen
-```js name="Common screen options" snack version=7
+```js name="Common screen options" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -437,10 +446,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -487,11 +495,12 @@ export default function App() {
-```js name="Common screen options" snack version=7
+```js name="Common screen options" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -499,10 +508,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -565,7 +573,7 @@ Sometimes you need more control than just changing the text and styles of your t
-```js name="Custom title" snack version=7
+```js name="Custom title" snack
import * as React from 'react';
import { Text, View, Image } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
@@ -612,7 +620,7 @@ export default function App() {
-```js name="Custom title" snack version=7
+```js name="Custom title" snack
import * as React from 'react';
import { Text, View, Image } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
@@ -663,6 +671,9 @@ export default function App() {
}
```
+
+
+You might be wondering, why `headerTitle` when we provide a component and not `title`, like before? The reason is that `headerTitle` is a property that is specific to stack navigators, the `headerTitle` defaults to a `Text` component that displays the `title`.
@@ -678,6 +689,6 @@ You can read the full list of available `options` for screens inside of a native
## Summary
-- You can customize the header inside of the `options` property of your screens. Read the full list of options [in the API reference](native-stack-navigator.md#options).
-- The `options` property can be an object or a function. When it is a function, it is provided with an object with the `navigation` and `route` objects.
-- You can also specify shared `screenOptions` in the stack navigator configuration when you initialize it. This will apply to all screens in the navigator.
+- You can customize the header inside of the [`options`](screen-options.md) property of your screens. Read the full list of options [in the API reference](native-stack-navigator.md#options).
+- The `options` property can be an object or a function. When it is a function, it is provided with an object with the [`navigation`](navigation-object.md) and [`route`](route-object.md) objects.
+- You can also specify shared [`screenOptions`](screen-options.md#screenoptions-prop-on-the-navigator) in the stack navigator configuration when you initialize it. This will apply to all screens in the navigator.
diff --git a/versioned_docs/version-7.x/hello-react-navigation.md b/versioned_docs/version-7.x/hello-react-navigation.md
index 726d1517eb7..74e4e98f602 100755
--- a/versioned_docs/version-7.x/hello-react-navigation.md
+++ b/versioned_docs/version-7.x/hello-react-navigation.md
@@ -18,7 +18,7 @@ Let's start by demonstrating the most common navigator, `createNativeStackNaviga
The libraries we've installed so far are the building blocks and shared foundations for navigators, and each navigator in React Navigation lives in its own library. To use the native stack navigator, we need to install [`@react-navigation/native-stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack) :
```bash npm2yarn
-npm install @react-navigation/native-stack@next
+npm install @react-navigation/native-stack
```
:::info
@@ -27,16 +27,24 @@ npm install @react-navigation/native-stack@next
:::
-### Creating a native stack navigator
+## Installing the elements library
+
+The [`@react-navigation/elements`](elements.md) library provides a set of components that are designed to work well with React Navigation. We'll use a few of these components in this guide. So let's install it first:
+
+```bash npm2yarn
+npm install @react-navigation/elements
+```
+
+## Creating a native stack navigator
`createNativeStackNavigator` is a function that takes a configuration object containing the screens and customization options. The screens are React Components that render the content displayed by the navigator.
-`createStaticNavigation` is a function that takes the navigator defined earlier and returns a component that can be rendered in the app. It's only called once in the app.
+`createStaticNavigation` is a function that takes the navigator defined earlier and returns a component that can be rendered in the app. It's only called once in the app. Usually, we'd render the returned component at the root of our app, which is usually the component exported from `App.js`, `App.tsx` etc., or used with `AppRegistry.registerComponent`, `Expo.registerRootComponent` etc.
-```js name="Native Stack Example" snack version=7
+```js name="Native Stack Example" snack
// In App.js in a new project
import * as React from 'react';
@@ -65,14 +73,20 @@ export default function App() {
}
```
+:::warning
+
+In a typical React Native app, the `createStaticNavigation` function should be only used once in your app at the root.
+
+:::
+
`createNativeStackNavigator` is a function that returns an object containing 2 properties: `Screen` and `Navigator`. Both of them are React components used for configuring the navigator. The `Navigator` should contain `Screen` elements as its children to define the configuration for routes.
-`NavigationContainer` is a component that manages our navigation tree and contains the [navigation state](navigation-state.md). This component must wrap all the navigators in the app. Usually, we'd render this component at the root of our app, which is usually the component exported from `App.js`.
+`NavigationContainer` is a component that manages our navigation tree and contains the [navigation state](navigation-state.md). This component must wrap all the navigators in the app. Usually, we'd render this component at the root of our app, which is usually the component exported from `App.js`, `App.tsx` etc., or used with `AppRegistry.registerComponent`, `Expo.registerRootComponent` etc.
-```js name="Native Stack Example" snack version=7
+```js name="Native Stack Example" snack
// In App.js in a new project
import * as React from 'react';
@@ -107,6 +121,12 @@ export default function App() {
}
```
+:::warning
+
+In a typical React Native app, the `NavigationContainer` should be only used once in your app at the root. You shouldn't nest multiple `NavigationContainer`s unless you have a specific use case for them.
+
+:::
+
@@ -120,7 +140,7 @@ The casing of the route name doesn't matter -- you can use lowercase `home` or c
:::
-### Configuring the navigator
+## Configuring the navigator
All of the route configuration is specified as props to our navigator. We haven't passed any props to our navigator, so it just uses the default configuration.
@@ -129,7 +149,7 @@ Let's add a second screen to our native stack navigator and configure the `Home`
-```js name="Native Stack Example" snack version=7
+```js name="Native Stack Example" snack
import * as React from 'react';
import { View, Text } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
@@ -174,7 +194,7 @@ Now our stack has two _routes_, a `Home` route and a `Details` route. A route ca
-```js name="Native Stack Example" snack version=7
+```js name="Native Stack Example" snack
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
@@ -232,7 +252,7 @@ When using the dynamic API, the `component` prop accepts a component, not a rend
Here, the `Home` route corresponds to the `HomeScreen` component, and the `Details` route corresponds to the `DetailsScreen` component. The initial route for the stack is the `Home` route. Try changing it to `Details` and reload the app (React Native's Fast Refresh won't update changes from `initialRouteName`, as you might expect), notice that you will now see the `Details` screen. Then change it back to `Home` and reload once more.
-### Specifying options
+## Specifying options
Each screen in the navigator can specify some options for the navigator, such as the title to render in the header.
@@ -258,7 +278,7 @@ This will let us specify additional options for the screen.
Now, we can add an `options` property:
-```js name="Options for Screen" snack version=7
+```js name="Options for Screen" snack
import * as React from 'react';
import { View, Text } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
@@ -306,7 +326,7 @@ export default function App() {
Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can add a `screenOptions` property to the configuration:
-```js name="Common options for Screens" snack version=7
+```js name="Common options for Screens" snack
import * as React from 'react';
import { View, Text } from 'react-native';
import { createStaticNavigation } from '@react-navigation/native';
@@ -360,7 +380,7 @@ export default function App() {
Any customization options can be passed in the `options` prop for each screen component:
-```js name="Options for Screen" snack version=7
+```js name="Options for Screen" snack
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
@@ -411,7 +431,7 @@ export default function App() {
Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can pass a `screenOptions` prop to the navigator:
-```js name="Common options for Screens" snack version=7
+```js name="Common options for Screens" snack
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
@@ -469,7 +489,7 @@ export default function App() {
-### Passing additional props
+## Passing additional props
@@ -481,7 +501,7 @@ Passing additional props to a screen is not supported in the static API.
Sometimes we might want to pass additional props to a screen. We can do that with 2 approaches:
-1. Use [React context](https://reactjs.org/docs/context.html) and wrap the navigator with a context provider to pass data to the screens (recommended).
+1. Use [React context](https://react.dev/reference/react/useContext) and wrap the navigator with a context provider to pass data to the screens (recommended).
2. Use a render callback for the screen instead of specifying a `component` prop:
```js
@@ -493,7 +513,7 @@ Sometimes we might want to pass additional props to a screen. We can do that wit
:::warning
-By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) or [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) for your screen components to avoid performance issues.
+By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://react.dev/reference/react/memo) or [`React.PureComponent`](https://react.dev/reference/react/PureComponent) for your screen components to avoid performance issues.
:::
@@ -504,25 +524,32 @@ By default, React Navigation applies optimizations to screen components to preve
The natural question at this point is: "how do I go from the `Home` route to the `Details` route?". That is covered in the [next section](navigating.md).
+
+Using with TypeScript
+
+If you are using TypeScript, you will need to specify the types accordingly. You can check [Type checking with TypeScript](typescript.md) after going through the fundamentals for more details. For now, we won't be covering TypeScript in the examples.
+
+
+
## Summary
- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens.
-- `createNativeStackNavigator` is a function that takes the screens configuration and renders our content.
+- [`createNativeStackNavigator`](native-stack-navigator.md) is a function that takes the screens configuration and renders our content.
- Each property under screens refers to the name of the route, and the value is the component to render for the route.
-- To specify what the initial route in a stack is, provide an `initialRouteName` option for the navigator.
-- To specify screen-specific options, we can specify an `options` property, and for common options, we can specify `screenOptions`.
+- To specify what the initial route in a stack is, provide an [`initialRouteName`](navigator.md#initial-route-name) option for the navigator.
+- To specify screen-specific options, we can specify an [`options`](screen-options.md#options-prop-on-screen) property, and for common options, we can specify [`screenOptions`](screen-options.md#screenoptions-prop-on-the-navigator).
- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens.
-- `Stack.Navigator` is a component that takes route configuration as its children with additional props for configuration and renders our content.
-- Each `Stack.Screen` component takes a `name` prop which refers to the name of the route and `component` prop which specifies the component to render for the route. These are the 2 required props.
-- To specify what the initial route in a stack is, provide an `initialRouteName` as the prop for the navigator.
-- To specify screen-specific options, we can pass an `options` prop to `Stack.Screen`, and for common options, we can pass `screenOptions` to `Stack.Navigator`.
+- [`Stack.Navigator`](native-stack-navigator.md) is a component that takes route configuration as its children with additional props for configuration and renders our content.
+- Each [`Stack.Screen`](screen.md) component takes a [`name`](screen.md#name) prop which refers to the name of the route and [`component`](screen.md#component) prop which specifies the component to render for the route. These are the 2 required props.
+- To specify what the initial route in a stack is, provide an [`initialRouteName`](navigator.md#initial-route-name) as the prop for the navigator.
+- To specify screen-specific options, we can pass an [`options`](screen-options.md#options-prop-on-screen) prop to `Stack.Screen`, and for common options, we can pass [`screenOptions`](screen-options.md#screenoptions-prop-on-the-navigator) to `Stack.Navigator`.
diff --git a/versioned_docs/version-7.x/hiding-tabbar-in-screens.md b/versioned_docs/version-7.x/hiding-tabbar-in-screens.md
index 6df6487af2c..345d36b62db 100644
--- a/versioned_docs/version-7.x/hiding-tabbar-in-screens.md
+++ b/versioned_docs/version-7.x/hiding-tabbar-in-screens.md
@@ -1,11 +1,44 @@
---
id: hiding-tabbar-in-screens
title: Hiding tab bar in specific screens
-sidebar_label: Hiding tab bar in specific screens
+sidebar_label: Hiding tab bar in screens
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Sometimes we may want to hide the tab bar in specific screens in a stack navigator nested in a tab navigator. Let's say we have 5 screens: `Home`, `Feed`, `Notifications`, `Profile` and `Settings`, and your navigation structure looks like this:
+
+
+
+```js name="Hiding tab bar in screens"
+const HomeStack = createNativeStackNavigator({
+ screens: {
+ Home: Home,
+ Profile: Profile,
+ Settings: Settings,
+ },
+});
+
+const MyTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeStack,
+ Feed: Feed,
+ Notifications: Notifications,
+ },
+});
+
+const Navigation = createStaticNavigation(MyTabs);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
```js
function HomeStack() {
return (
@@ -30,32 +63,135 @@ function App() {
}
```
+
+
+
With this structure, when we navigate to the `Profile` or `Settings` screen, the tab bar will still stay visible over those screens.
But if we want to show the tab bar only on the `Home`, `Feed` and `Notifications` screens, but not on the `Profile` and `Settings` screens, we'll need to change the navigation structure. The easiest way to achieve this is to nest the tab navigator inside the first screen of the stack instead of nesting stack inside tab navigator:
-
+
+
-```js
+```js name="Hiding tabbar" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
+
+function EmptyScreen() {
+ return ;
+}
+
+function Home() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+// codeblock-focus-start
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Home: Home,
+ Feed: EmptyScreen,
+ Notifications: EmptyScreen,
+ },
+});
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeTabs,
+ Profile: EmptyScreen,
+ Settings: EmptyScreen,
+ },
+});
+
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Hiding tabbar" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
+
+const Tab = createBottomTabNavigator();
+const Stack = createNativeStackNavigator();
+
+function EmptyScreen() {
+ return ;
+}
+
+function Home() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+// codeblock-focus-start
function HomeTabs() {
return (
-
-
+
+
);
}
function App() {
return (
-
-
-
-
-
+
+
+
+
+
+
+
);
}
+// codeblock-focus-end
+
+export default App;
```
+
+
+
After re-organizing the navigation structure, now if we navigate to the `Profile` or `Settings` screens, the tab bar won't be visible over the screen anymore.
diff --git a/versioned_docs/version-7.x/limitations.md b/versioned_docs/version-7.x/limitations.md
index 8ef876a59ff..0958770e95f 100755
--- a/versioned_docs/version-7.x/limitations.md
+++ b/versioned_docs/version-7.x/limitations.md
@@ -4,7 +4,7 @@ title: Limitations
sidebar_label: Limitations
---
-As a potential user of the library, it's important to know what you can and cannot do with it. Armed with this knowledge, you may choose to adopt a different library such as [`react-native=navigation`](https://github.com/wix/react-native-navigation) instead. We discuss the high level design decisions in the [pitch & anti-pitch](pitch.md) section, and here we will cover some of the use cases that are either not supported or are so difficult to do that they may as well be impossible. If any of the following limitations are dealbreakers for your app, React Navigation might not be for you.
+As a potential user of the library, it's important to know what you can and cannot do with it. Armed with this knowledge, you may choose to adopt a different library such as [`react-native-navigation`](https://github.com/wix/react-native-navigation) instead. We discuss the high level design decisions in the [pitch & anti-pitch](pitch.md) section, and here we will cover some of the use cases that are either not supported or are so difficult to do that they may as well be impossible. If any of the following limitations are dealbreakers for your app, React Navigation might not be for you.
## Limited right-to-left (RTL) layout support
diff --git a/versioned_docs/version-7.x/material-top-tab-navigator.md b/versioned_docs/version-7.x/material-top-tab-navigator.md
index 767be1661d6..3cf4b61bd5d 100755
--- a/versioned_docs/version-7.x/material-top-tab-navigator.md
+++ b/versioned_docs/version-7.x/material-top-tab-navigator.md
@@ -6,11 +6,9 @@ sidebar_label: Material Top Tabs
A material-design themed tab bar on the top of the screen that lets you switch between different routes by tapping the tabs or swiping horizontally. Transitions are animated by default. Screen components for each route are mounted immediately.
-
-
-
-
-
+
+
+
This wraps [`react-native-tab-view`](tab-view.md). If you want to use the tab view without React Navigation integration, use the library directly instead.
@@ -19,10 +17,13 @@ This wraps [`react-native-tab-view`](tab-view.md). If you want to use the tab vi
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/material-top-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/material-top-tabs):
```bash npm2yarn
-npm install @react-navigation/material-top-tabs@next
+npm install @react-navigation/material-top-tabs
```
-Then, you need to install [`react-native-pager-view`](https://github.com/callstack/react-native-pager-view) which is required by the navigator.
+The navigator depends on [`react-native-pager-view`](https://github.com/callstack/react-native-pager-view) for rendering the pages.
+
+
+
If you have a Expo managed project, in your project directory, run:
@@ -30,13 +31,19 @@ If you have a Expo managed project, in your project directory, run:
npx expo install react-native-pager-view
```
+
+
+
If you have a bare React Native project, in your project directory, run:
```bash npm2yarn
npm install react-native-pager-view
```
-If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
+
+
+
+If you're on a Mac and developing for iOS, you also need to install [pods](https://cocoapods.org/) to complete the linking.
```bash
npx pod-install ios
@@ -49,10 +56,14 @@ To use this navigator, import it from `@react-navigation/material-top-tabs`:
-```js name="Material Top Tab Navigator" snack version=7
+```js name="Material Top Tab Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
-import { createStaticNavigation, useNavigation } from '@react-navigation/native';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
@@ -63,10 +74,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -77,10 +87,7 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Home')}
- />
+ navigation.navigate('Home')}>Go to Home
);
}
@@ -104,10 +111,11 @@ export default function App() {
-```js name="Material Top Tab Navigator" snack version=7
+```js name="Material Top Tab Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
@@ -129,10 +137,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -143,10 +150,7 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Home')}
- />
+ navigation.navigate('Home')}>Go to Home
);
}
@@ -167,19 +171,7 @@ export default function App() {
### Props
-The `Tab.Navigator` component accepts following props:
-
-#### `id`
-
-Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator.
-
-#### `initialRouteName`
-
-The name of the route to render on first load of the navigator.
-
-#### `screenOptions`
-
-Default options to use for the screens in the navigator.
+In addition to the [common props](navigator.md#configuration) shared by all navigators, the material top tabs navigator component accepts the following additional props:
#### `backBehavior`
@@ -215,10 +207,6 @@ Object containing the initial height and width of the screens. Passing this will
}
```
-#### `sceneContainerStyle`
-
-Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping.
-
#### `style`
Style to apply to the tab view container.
@@ -232,9 +220,13 @@ Example:
```js
-import { Animated, View, TouchableOpacity } from 'react-native';
+import { Animated, View, TouchableOpacity, Platform } from 'react-native';
+import { useLinkBuilder, useTheme } from '@react-navigation/native';
function MyTabBar({ state, descriptors, navigation, position }) {
+ const { colors } = useTheme();
+ const { buildHref } = useLinkBuilder();
+
return (
{state.routes.map((route, index) => {
@@ -243,8 +235,8 @@ function MyTabBar({ state, descriptors, navigation, position }) {
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
- ? options.title
- : route.name;
+ ? options.title
+ : route.name;
const isFocused = state.index === index;
@@ -256,8 +248,7 @@ function MyTabBar({ state, descriptors, navigation, position }) {
});
if (!isFocused && !event.defaultPrevented) {
- // The `merge: true` option makes sure that the params inside the tab screen are preserved
- navigation.navigate({ name: route.name, merge: true });
+ navigation.navigate(route.name, route.params);
}
};
@@ -271,20 +262,21 @@ function MyTabBar({ state, descriptors, navigation, position }) {
const inputRange = state.routes.map((_, i) => i);
const opacity = position.interpolate({
inputRange,
- outputRange: inputRange.map(i => (i === index ? 1 : 0)),
+ outputRange: inputRange.map((i) => (i === index ? 1 : 0)),
});
return (
-
+
{label}
@@ -296,9 +288,9 @@ function MyTabBar({ state, descriptors, navigation, position }) {
// ...
- }>
- {...}
-
+ }>
+ {/* ... */}
+ ;
```
This example will render a basic tab bar with labels.
@@ -309,12 +301,14 @@ Note that you **cannot** use the `useNavigation` hook inside the `tabBar` since
function MyTabBar({ navigation }) {
return (
{
// Navigate using the `navigation` prop that you received
+ // highlight-next-line
navigation.navigate('SomeScreen');
}}
- />
+ >
+ Go somewhere
+
);
}
```
@@ -383,7 +377,7 @@ Style object for the tab bar indicator.
Style object for the view containing the tab bar indicator.
-#### `tabBarTestID`
+#### `tabBarButtonTestID`
ID to locate this tab button in tests.
@@ -413,10 +407,6 @@ Boolean indicating whether to make the tab bar scrollable.
If you set this to `true`, you should also specify a width in `tabBarItemStyle` to improve the performance of initial render.
-#### `tabBarIconStyle`
-
-Style object for the tab icon container.
-
#### `tabBarLabelStyle`
Style object for the tab label.
@@ -455,6 +445,10 @@ This view is usually only shown for a split second. Keep it lightweight.
By default, this renders `null`.
+#### `sceneStyle`
+
+Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping.
+
### Events
The navigator can [emit events](navigation-events.md) on certain actions. Supported events are:
@@ -519,41 +513,30 @@ Navigates to an existing screen in the tab navigator. The method accepts followi
navigation.jumpTo('Profile', { name: 'Michaś' });
```
-## Example
+### Hooks
-
+The material top tab navigator exports the following hooks:
+
+#### `useTabAnimation`
+
+This hook returns an object containing an animated value that represents the current position of the tabs. This can be used to animate elements based on the swipe position of the tabs, such as the tab indicator:
```js
-import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+import { Animated } from 'react-native';
+import { useTabAnimation } from '@react-navigation/material-top-tabs';
-const Tab = createMaterialTopTabNavigator();
+function MyView() {
+ const { position } = useTabAnimation();
-function MyTabs() {
return (
-
-
-
-
-
+ />
);
}
```
diff --git a/versioned_docs/version-7.x/modal.md b/versioned_docs/version-7.x/modal.md
index be5ff7a74b1..e9921b5d235 100755
--- a/versioned_docs/version-7.x/modal.md
+++ b/versioned_docs/version-7.x/modal.md
@@ -4,6 +4,9 @@ title: Opening a modal
sidebar_label: Opening a modal
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+

A modal displays content that temporarily blocks interactions with the main view.
@@ -12,17 +15,38 @@ A modal is like a popup — it usually has a different transition animation,
## Creating a stack with modal screens
-
+
+
+
+```js name="Modal" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
-```js
-function HomeScreen({ navigation }) {
return (
This is the home screen!
- navigation.navigate('MyModal')}
- title="Open Modal"
- />
+ navigation.navigate('MyModal')}>Open Modal
+
+ );
+}
+
+function ModalScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is a modal!
+ navigation.goBack()}>Dismiss
);
}
@@ -35,39 +59,133 @@ function DetailsScreen() {
);
}
-function ModalScreen({ navigation }) {
+const HomeStack = createStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ headerShown: false,
+ },
+ },
+ Details: {
+ screen: DetailsScreen,
+ options: {
+ headerShown: false,
+ },
+ },
+ },
+});
+
+const RootStack = createStackNavigator({
+ groups: {
+ Home: {
+ screens: {
+ App: {
+ screen: HomeStack,
+ options: { title: 'My App' },
+ },
+ },
+ },
+ // highlight-start
+ Modal: {
+ screenOptions: {
+ presentation: 'modal',
+ },
+ screens: {
+ MyModal: ModalScreen,
+ },
+ },
+ // highlight-end
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Modal" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen!
+ navigation.navigate('MyModal')}>Open Modal
+
+ );
+}
+
+function ModalScreen() {
+ const navigation = useNavigation();
+
return (
This is a modal!
- navigation.goBack()} title="Dismiss" />
+ navigation.goBack()}>Dismiss
+
+ );
+}
+
+function DetailsScreen() {
+ return (
+
+ Details
);
}
const RootStack = createStackNavigator();
-function RootStackScreen() {
+function App() {
return (
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ // highlight-start
+
+
+
+ // highlight-end
+
+
);
}
+// codeblock-focus-end
+
+export default App;
```
+
+
+
+
+
+
+
Here, we are creating 2 groups of screens using the `RootStack.Group` component. The first group is for our regular screens, and the second group is for our modal screens. For the modal group, we have specified `presentation: 'modal'` in `screenOptions`. This will apply this option to all the screens inside the group. This option will change the animation for the screens to animate from bottom-to-top rather than right to left. The `presentation` option for stack navigator can be either `card` (default) or `modal`. The `modal` behavior slides the screen in from the bottom and allows the user to swipe down from the top to dismiss it on iOS.
Instead of specifying this option for a group, it's also possible to specify it for a single screen using the `options` prop on `RootStack.Screen`.
## Summary
-- To change the type of transition on a stack navigator you can use the `presentation` option.
+- To change the type of transition on a stack navigator you can use the [`presentation`](native-stack-navigator.md#presentation) option.
- When `presentation` is set to `modal`, the screens behave like a modal, i.e. they have a bottom to top transition and may show part of the previous screen in the background.
- Setting `presentation: 'modal'` on a group makes all the screens in the group modals, so to use non-modal transitions on other screens, we add another group with the default configuration.
diff --git a/versioned_docs/version-7.x/more-resources.md b/versioned_docs/version-7.x/more-resources.md
index b76b7398f9d..8e71db8cf3a 100755
--- a/versioned_docs/version-7.x/more-resources.md
+++ b/versioned_docs/version-7.x/more-resources.md
@@ -1,7 +1,7 @@
---
id: more-resources
-title: More Resources
-sidebar_label: More Resources
+title: More resources
+sidebar_label: More resources
---
## Talks
diff --git a/versioned_docs/version-7.x/multiple-drawers.md b/versioned_docs/version-7.x/multiple-drawers.md
index 7726ea98674..8b369a690a7 100644
--- a/versioned_docs/version-7.x/multiple-drawers.md
+++ b/versioned_docs/version-7.x/multiple-drawers.md
@@ -4,6 +4,9 @@ title: Multiple drawers
sidebar_label: Multiple drawers
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Sometimes we want to have multiple drawers on the same screen: one on the left and one on the right. This can be achieved in 2 ways:
1. By using [`react-native-drawer-layout`](drawer-layout.md) directly (Recommended).
@@ -15,16 +18,79 @@ When we have multiple drawers, only one of them shows the list of screens. The s
In such cases, we can use [`react-native-drawer-layout`](drawer-layout.md) directly to render the second drawer. The drawer navigator will be used to render the first drawer and can be nested inside the second drawer:
+
+
+
+```js
+import * as React from 'react';
+import { View } from 'react-native';
+import { Drawer } from 'react-native-drawer-layout';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.openDrawer()}>Open drawer
+
+ );
+}
+
+const LeftDrawerScreen = createDrawerNavigator({
+ screenOptions: {
+ drawerPosition: 'left',
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+
+function RightDrawerScreen() {
+ const [rightDrawerOpen, setRightDrawerOpen] = React.useState(false);
+
+ return (
+ setRightDrawerOpen(true)}
+ onClose={() => setRightDrawerOpen(false)}
+ drawerPosition="right"
+ renderDrawerContent={() => <>{/* Right drawer content */}>}
+ >
+
+
+ );
+}
+
+const Navigation = createStaticNavigation(RightDrawerScreen);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
```js
import * as React from 'react';
-import { Button, View } from 'react-native';
+import { View } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
+import { useNavigation } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
-function HomeScreen({ navigation }) {
return (
- navigation.openDrawer()} title="Open drawer" />
+ navigation.openDrawer()}>Open drawer
);
}
@@ -64,28 +130,104 @@ export default function App() {
}
```
+
+
+
But there is one problem. When we call `navigation.openDrawer()` in our `HomeScreen`, it always opens the left drawer. We don't have access to the right drawer via the `navigation` object since it's not a navigator.
To solve this, we need to use context API to pass down a function to control the right drawer:
+
+
+
+```js
+import * as React from 'react';
+import { View } from 'react-native';
+import { Drawer } from 'react-native-drawer-layout';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+const RightDrawerContext = React.createContext();
+
+function HomeScreen() {
+ const { openRightDrawer } = React.useContext(RightDrawerContext);
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.openDrawer()}>Open left drawer
+ openRightDrawer()}>Open right drawer
+
+ );
+}
+
+const LeftDrawerScreen = createDrawerNavigator({
+ screenOptions: {
+ drawerPosition: 'left',
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+
+function RightDrawerScreen() {
+ const [rightDrawerOpen, setRightDrawerOpen] = React.useState(false);
+
+ const value = React.useMemo(
+ () => ({
+ openRightDrawer: () => setRightDrawerOpen(true),
+ closeRightDrawer: () => setRightDrawerOpen(false),
+ }),
+ []
+ );
+
+ return (
+ setRightDrawerOpen(true)}
+ onClose={() => setRightDrawerOpen(false)}
+ drawerPosition="right"
+ renderDrawerContent={() => <>{/* Right drawer content */}>}
+ >
+
+
+
+
+ );
+}
+
+const Navigation = createStaticNavigation(RightDrawerScreen);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
```js
import * as React from 'react';
-import { Button, View } from 'react-native';
+import { View } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
+import { useNavigation } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
const RightDrawerContext = React.createContext();
-function HomeScreen({ navigation }) {
+function HomeScreen() {
+ const navigation = useNavigation();
const { openRightDrawer } = React.useContext(RightDrawerContext);
return (
- navigation.openDrawer()}
- title="Open left drawer"
- />
- openRightDrawer()} title="Open right drawer" />
+ navigation.openDrawer()}>Open left drawer
+ openRightDrawer()}>Open right drawer
);
}
@@ -135,6 +277,9 @@ export default function App() {
}
```
+
+
+
Here, we are using the `RightDrawerContext` to pass down the `openRightDrawer` function to the `HomeScreen`. Then we use `openRightDrawer` to open the right drawer.
## Nesting 2 drawer navigators
@@ -143,18 +288,71 @@ An alternative approach is to nest 2 [drawer navigators](drawer-navigator.md) in
Here we have 2 drawer navigators nested inside each other, one is positioned on left and the other on the right:
-
+
+
-```js
+```js name="Multiple drawers" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.openDrawer()}>Open drawer
+
+ );
+}
+
+const LeftDrawerScreen = createDrawerNavigator({
+ screenOptions: {
+ drawerPosition: 'left',
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+
+const RightDrawerScreen = createDrawerNavigator({
+ screenOptions: {
+ drawerPosition: 'right',
+ headerShown: false,
+ },
+ screens: {
+ HomeDrawer: LeftDrawerScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(RightDrawerScreen);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Multiple drawers" snack
import * as React from 'react';
-import { Button, View } from 'react-native';
+import { View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
-import { NavigationContainer } from '@react-navigation/native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
-function HomeScreen({ navigation }) {
return (
- navigation.openDrawer()} title="Open drawer" />
+ navigation.openDrawer()}>Open drawer
);
}
@@ -190,40 +388,114 @@ export default function App() {
}
```
+
+
+
+
+
+
+
But there is one problem. When we call `navigation.openDrawer()` in our `HomeScreen`, it always opens the left drawer since it's the immediate parent of the screen.
To solve this, we need to use [`navigation.getParent`](navigation-object.md#getparent) to refer to the right drawer which is the parent of the left drawer. So our code would look like:
```js
- navigation.openDrawer()} title="Open left drawer" />
- navigation.getParent().openDrawer()} title="Open right drawer" />
+ navigation.openDrawer()} >Open left drawer
+ navigation.getParent().openDrawer()}>Open right drawer
```
-However, this means that our button needs to know about the parent navigators, which isn't ideal. If our button is further nested inside other navigators, it'd need multiple `getParent()` calls. To address this, we can use the [`id` prop](drawer-navigator.md#id) to identify the parent navigator.
+However, this means that our button needs to know about the parent navigators, which isn't ideal. If our button is further nested inside other navigators, it'd need multiple `getParent()` calls. To address this, we can use the [`id` prop](navigator.md#id) to identify the parent navigator.
To customize the contents of the drawer, we can use the [`drawerContent` prop](drawer-navigator.md#drawercontent) to pass in a function that renders a custom component.
The final code would look like this:
-
+
+
-```js
+```js name="Multiple drawers navigators" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.getParent('LeftDrawer').openDrawer()}>
+ Open left drawer
+
+ navigation.getParent('RightDrawer').openDrawer()}>
+ Open right drawer
+
+
+ );
+}
+
+function RightDrawerContent() {
+ return (
+
+ This is the right drawer
+
+ );
+}
+
+const LeftDrawerScreen = createDrawerNavigator({
+ id: 'LeftDrawer',
+ screenOptions: {
+ drawerPosition: 'left',
+ },
+ screens: {
+ Home: HomeScreen,
+ },
+});
+
+const RightDrawerScreen = createDrawerNavigator({
+ id: 'RightDrawer',
+ drawerContent: (props) => ,
+ screenOptions: {
+ drawerPosition: 'right',
+ headerShown: false,
+ },
+ screens: {
+ HomeDrawer: LeftDrawerScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(RightDrawerScreen);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Multiple drawers navigators" snack
import * as React from 'react';
-import { Button, Text, View } from 'react-native';
+import { Text, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
-import { NavigationContainer } from '@react-navigation/native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
-function HomeScreen({ navigation }) {
return (
- navigation.getParent('LeftDrawer').openDrawer()}
- title="Open left drawer"
- />
- navigation.getParent('RightDrawer').openDrawer()}
- title="Open right drawer"
- />
+ navigation.getParent('LeftDrawer').openDrawer()}>
+ Open left drawer
+
+ navigation.getParent('RightDrawer').openDrawer()}>
+ Open right drawer
+
);
}
@@ -275,6 +547,9 @@ export default function App() {
}
```
+
+
+
Here, we are passing `"LeftDrawer"` and `"RightDrawer"` strings (you can use any string here) in the `id` prop of the drawer navigators. Then we use `navigation.getParent('LeftDrawer').openDrawer()` to open the left drawer and `navigation.getParent('RightDrawer').openDrawer()` to open the right drawer.
## Summary
@@ -282,4 +557,4 @@ Here, we are passing `"LeftDrawer"` and `"RightDrawer"` strings (you can use any
- To have multiple drawers, you can use [`react-native-drawer-layout`](drawer-layout.md) directly in combination with a drawer navigator.
- The [`drawerPosition`](drawer-layout.md#drawerposition) prop can be used to position the drawer on the right.
- The methods to control the drawer can be passed down using context API when using [`react-native-drawer-layout`](drawer-layout.md).
-- When nesting multiple navigators, you can use [`navigation.getParent`](navigation-object.md#getparent) in combination with the [`id` prop](drawer-navigator.md#id) to refer to the desired drawer.
+- When nesting multiple navigators, you can use [`navigation.getParent`](navigation-object.md#getparent) in combination with the [`id` prop](navigator.md#id) to refer to the desired drawer.
diff --git a/versioned_docs/version-7.x/native-bottom-tab-navigator.md b/versioned_docs/version-7.x/native-bottom-tab-navigator.md
new file mode 100755
index 00000000000..d712521ff07
--- /dev/null
+++ b/versioned_docs/version-7.x/native-bottom-tab-navigator.md
@@ -0,0 +1,469 @@
+---
+id: native-bottom-tab-navigator
+title: Native Bottom Tabs Navigator
+sidebar_label: Native Bottom Tabs
+---
+
+:::warning
+
+This navigator is currently experimental. The API will change in future releases.
+
+Currently only iOS and Android are supported. Use [`createBottomTabNavigator`](bottom-tab-navigator.md) for web support.
+
+:::
+
+Native Bottom Tabs displays screens with a tab bar to switch between them.
+
+
+
+
+
+
+
+
+
+The navigator uses native components on iOS and Android for better platform integration. On iOS, it uses `UITabBarController` and on Android, it uses `BottomNavigationView`.
+
+## Installation
+
+To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/bottom-tabs):
+
+```bash npm2yarn
+npm install @react-navigation/bottom-tabs
+```
+
+The navigator requires React Native 0.79 or above is required. If you're using [Expo](https://expo.dev/), it requires SDK 53 or above.
+
+## Usage
+
+To use this navigator, import it from `@react-navigation/bottom-tabs/unstable`:
+
+
+
+
+```js name="Bottom Tab Navigator"
+import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
+
+const MyTabs = createNativeBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js name="Bottom Tab Navigator"
+import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
+
+const Tab = createNativeBottomTabNavigator();
+
+function MyTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+
+
+
+## Notes
+
+- Liquid Glass effect on iOS 26+ requires your app to be built with Xcode 26 or above.
+- On Android, at most 5 tabs are supported. This is a limitation of the underlying native component.
+
+## API Definition
+
+### Props
+
+In addition to the [common props](navigator.md#configuration) shared by all navigators, the bottom tab navigator accepts the following additional props:
+
+#### `backBehavior`
+
+This controls what happens when `goBack` is called in the navigator. This includes pressing the device's back button or back gesture on Android.
+
+It supports the following values:
+
+- `firstRoute` - return to the first screen defined in the navigator (default)
+- `initialRoute` - return to initial screen passed in `initialRouteName` prop, if not passed, defaults to the first screen
+- `order` - return to screen defined before the focused screen
+- `history` - return to last visited screen in the navigator; if the same screen is visited multiple times, the older entries are dropped from the history
+- `fullHistory` - return to last visited screen in the navigator; doesn't drop duplicate entries unlike `history` - this behavior is useful to match how web pages work
+- `none` - do not handle back button
+
+### Options
+
+The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Tab.Navigator` or `options` prop of `Tab.Screen`.
+
+#### `title`
+
+Generic title that can be used as a fallback for `headerTitle` and `tabBarLabel`.
+
+#### `tabBarSystemItem`
+
+Uses iOS built-in tab bar items with standard iOS styling and localized titles. Supported values:
+
+- `bookmarks`
+- `contacts`
+- `downloads`
+- `favorites`
+- `featured`
+- `history`
+- `more`
+- `mostRecent`
+- `mostViewed`
+- `recents`
+- `search`
+- `topRated`
+
+The [`tabBarIcon`](#tabbaricon) and [`tabBarLabel`](#tabbarlabel) options will override the icon and label from the system item. If you want to keep the system behavior on iOS, but need to provide icon and label for other platforms, use `Platform.OS` or `Platform.select` to conditionally set `undefined` for `tabBarIcon` and `tabBarLabel` on iOS.
+
+##### Search tab on iOS 26+
+
+The `tabBarSystemItem` option has special styling and behavior when set to `search` on iOS 26+.
+
+Additionally, when the `search` tab is selected, the tab bar transforms into a search field if the screen in the tab navigator or a nested [native stack navigator](native-stack-navigator.md) has [`headerSearchBarOptions`](native-stack-navigator.md#headersearchbaroptions) configured and the native header is shown with [`headerShown: true`](native-stack-navigator.md#headershown). This won't work if a custom header is provided with the `header` option.
+
+Example:
+
+```js
+tabBarSystemItem: 'search',
+headerShown: true,
+headerSearchBarOptions: {
+ placeholder: 'Search',
+},
+```
+
+
+
+
+
+#### `tabBarLabel`
+
+Title string of a tab displayed in the tab bar.
+
+Overrides the label provided by [`tabBarSystemItem`](#tabbarsystemitem) on iOS.
+
+If not provided, or set to `undefined`:
+
+- The system values are used if [`tabBarSystemItem`](#tabbarsystemitem) is set on iOS.
+- Otherwise, it falls back to the [`title`](#title) or route name.
+
+#### `tabBarLabelVisibilityMode`
+
+The label visibility mode for the tab bar items. Supported values:
+
+- `auto` - the system decides when to show or hide labels
+- `selected` - labels are shown only for the selected tab
+- `labeled` - labels are always shown
+- `unlabeled` - labels are never shown
+
+Only supported on Android.
+
+#### `tabBarLabelStyle`
+
+Style object for the tab label. Supported properties:
+
+- `fontFamily`
+- `fontSize`
+- `fontWeight`
+- `fontStyle`
+
+Example:
+
+```js
+tabBarLabelStyle: {
+ fontSize: 16,
+ fontFamily: 'Georgia',
+ fontWeight: 300,
+},
+```
+
+#### `tabBarIcon`
+
+Icon to display for the tab. It overrides the icon provided by [`tabBarSystemItem`](#tabbarsystemitem) on iOS.
+
+It can be an icon object or a function that given `{ focused: boolean, color: string, size: number }` returns an icon object.
+
+The icon can be of following types:
+
+- Local image - Supported on iOS and Android
+
+ ```js
+ tabBarIcon: {
+ type: 'image',
+ source: require('./path/to/icon.png'),
+ }
+ ```
+
+ On iOS, you can additionally pass a `tinted` property to control whether the icon should be tinted with the active/inactive color:
+
+ ```js
+ tabBarIcon: {
+ type: 'image',
+ source: require('./path/to/icon.png'),
+ tinted: false,
+ }
+ ```
+
+ The image is tinted by default.
+
+- [SF Symbols](https://developer.apple.com/sf-symbols/) name - Supported on iOS
+
+ ```js
+ tabBarIcon: {
+ type: 'sfSymbol',
+ name: 'heart',
+ }
+ ```
+
+- [Drawable resource](https://developer.android.com/guide/topics/resources/drawable-resource) name - Supported on Android
+
+ ```js
+ tabBarIcon: {
+ type: 'drawableResource',
+ name: 'sunny',
+ }
+ ```
+
+To render different icons for active and inactive states, you can use a function:
+
+```js
+tabBarIcon: ({ focused }) => {
+ return {
+ type: 'sfSymbol',
+ name: focused ? 'heart' : 'heart-outline',
+ };
+},
+```
+
+This is only supported on iOS. On Android, the icon specified for inactive state will be used for both active and inactive states.
+
+To provide different icons for different platforms, you can use [`Platform.select`](https://reactnative.dev/docs/platform-specific-code):
+
+```js
+tabBarIcon: Platform.select({
+ ios: {
+ type: 'sfSymbol',
+ name: 'heart',
+ },
+ android: {
+ type: 'drawableResource',
+ name: 'heart_icon',
+ },
+});
+```
+
+#### `tabBarBadge`
+
+Text to show in a badge on the tab icon. Accepts a `string` or a `number`.
+
+#### `tabBarBadgeStyle`
+
+Style for the badge on the tab icon. Supported properties:
+
+- `backgroundColor`
+- `color`
+
+Example:
+
+```js
+tabBarBadgeStyle: {
+ backgroundColor: 'yellow',
+ color: 'black',
+},
+```
+
+Only supported on Android.
+
+#### `tabBarActiveTintColor`
+
+Color for the icon and label in the active tab.
+
+#### `tabBarInactiveTintColor`
+
+Color for the icon and label in the inactive tabs.
+
+Only supported on Android.
+
+#### `tabBarActiveIndicatorColor`
+
+Background color of the active indicator.
+
+Only supported on Android.
+
+#### `tabBarActiveIndicatorEnabled`
+
+Whether the active indicator should be used. Defaults to `true`.
+
+Only supported on Android.
+
+#### `tabBarRippleColor`
+
+Color of the ripple effect when pressing a tab.
+
+Only supported on Android.
+
+#### `tabBarStyle`
+
+Style object for the tab bar. Supported properties:
+
+- `backgroundColor` - Only supported on Android and iOS 18 and below.
+- `shadowColor` - Only supported on iOS 18 and below.
+
+On iOS 26+, the background color automatically changes based on the content behind the tab bar and can't be overridden.
+
+#### `tabBarBlurEffect`
+
+Blur effect applied to the tab bar on iOS 18 and lower when tab screen is selected.
+
+Supported values:
+
+- `none` - no blur effect
+- `systemDefault` - default blur effect applied by the system
+- `extraLight`
+- `light`
+- `dark`
+- `regular`
+- `prominent`
+- `systemUltraThinMaterial`
+- `systemThinMaterial`
+- `systemMaterial`
+- `systemThickMaterial`
+- `systemChromeMaterial`
+- `systemUltraThinMaterialLight`
+- `systemThinMaterialLight`
+- `systemMaterialLight`
+- `systemThickMaterialLight`
+- `systemChromeMaterialLight`
+- `systemUltraThinMaterialDark`
+- `systemThinMaterialDark`
+- `systemMaterialDark`
+- `systemThickMaterialDark`
+- `systemChromeMaterialDark`
+
+Defaults to `systemDefault`.
+
+Only supported on iOS 18 and below.
+
+#### `tabBarControllerMode`
+
+The display mode for the tab bar. Supported values:
+
+- `auto` - the system sets the display mode based on the tab’s content
+- `tabBar` - the system displays the content only as a tab bar
+- `tabSidebar` - the tab bar is displayed as a sidebar
+
+Only supported on iOS 18 and above. Not supported on tvOS.
+
+#### `tabBarMinimizeBehavior`
+
+The minimize behavior for the tab bar. Supported values:
+
+- `auto` - resolves to the system default minimize behavior
+- `never` - the tab bar does not minimize
+- `onScrollDown` - the tab bar minimizes when scrolling down and
+ expands when scrolling back up
+- `onScrollUp` - the tab bar minimizes when scrolling up and expands
+ when scrolling back down
+
+Only supported on iOS 26 and above.
+
+
+
+
+
+#### `lazy`
+
+Whether this screen should render only after the first time it's accessed. Defaults to `true`. Set it to `false` if you want to render the screen on the initial render of the navigator.
+
+#### `popToTopOnBlur`
+
+Boolean indicating whether any nested stack should be popped to the top of the stack when navigating away from this tab. Defaults to `false`.
+
+It only works when there is a stack navigator (e.g. [stack navigator](stack-navigator.md) or [native stack navigator](native-stack-navigator.md)) nested under the tab navigator.
+
+### Header related options
+
+The navigator does not show a header by default. It renders a native stack header if `headerShown` is set to `true` in the screen options explicitly, or if a custom header is provided with the `header` option. Header related options require a header to be shown.
+
+It supports most of the [header related options supported in `@react-navigation/native-stack`](native-stack-navigator.md#header-related-options) apart from the options related to the back button (prefixed with `headerBack`).
+
+### Events
+
+The navigator can [emit events](navigation-events.md) on certain actions. Supported events are:
+
+#### `tabPress`
+
+This event is fired when the user presses the tab button for the current screen in the tab bar. By default a tab press does several things:
+
+- If the tab is not focused, tab press will focus that tab
+- If the tab is already focused:
+ - If the screen for the tab renders a scroll view, you can use [`useScrollToTop`](use-scroll-to-top.md) to scroll it to top
+ - If the screen for the tab renders a stack navigator, a `popToTop` action is performed on the stack
+
+The default behavior of the tab press is controlled natively and cannot be prevented.
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('tabPress', (e) => {
+ // Do something manually
+ // ...
+ });
+
+ return unsubscribe;
+}, [navigation]);
+```
+
+#### `transitionStart`
+
+This event is fired when the transition animation starts for the current screen.
+
+Example:
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('transitionStart', (e) => {
+ // Do something
+ });
+
+ return unsubscribe;
+}, [navigation]);
+```
+
+#### `transitionEnd`
+
+This event is fired when the transition animation ends for the current screen.
+
+Example:
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('transitionEnd', (e) => {
+ // Do something
+ });
+
+ return unsubscribe;
+}, [navigation]);
+```
+
+### Helpers
+
+The tab navigator adds the following methods to the navigation object:
+
+#### `jumpTo`
+
+Navigates to an existing screen in the tab navigator. The method accepts following arguments:
+
+- `name` - _string_ - Name of the route to jump to.
+- `params` - _object_ - Screen params to use for the destination route.
+
+```js
+navigation.jumpTo('Profile', { owner: 'Michaś' });
+```
diff --git a/versioned_docs/version-7.x/native-stack-navigator.md b/versioned_docs/version-7.x/native-stack-navigator.md
index 563a7005017..d0bd10b6a8a 100755
--- a/versioned_docs/version-7.x/native-stack-navigator.md
+++ b/versioned_docs/version-7.x/native-stack-navigator.md
@@ -6,6 +6,14 @@ sidebar_label: Native Stack
Native Stack Navigator provides a way for your app to transition between screens where each new screen is placed on top of a stack.
+
+
+
+
+
+
+
+
This navigator uses the native APIs `UINavigationController` on iOS and `Fragment` on Android so that navigation built with `createNativeStackNavigator` will behave exactly the same and have the same performance characteristics as apps built natively on top of those APIs. It also offers basic Web support using [`react-native-web`](https://github.com/necolas/react-native-web).
One thing to keep in mind is that while `@react-navigation/native-stack` offers native performance and exposes native features such as large title on iOS etc., it may not be as customizable as [`@react-navigation/stack`](stack-navigator.md) depending on your needs. So if you need more customization than what's possible in this navigator, consider using `@react-navigation/stack` instead - which is a more customizable JavaScript based implementation.
@@ -15,7 +23,7 @@ One thing to keep in mind is that while `@react-navigation/native-stack` offers
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/native-stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack):
```bash npm2yarn
-npm install @react-navigation/native-stack@next
+npm install @react-navigation/native-stack
```
## Usage
@@ -25,10 +33,14 @@ To use this navigator, import it from `@react-navigation/native-stack`:
-```js name="Native Stack Navigator" snack version=7
+```js name="Native Stack Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
-import { createStaticNavigation, useNavigation } from '@react-navigation/native';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createNativeStackNavigator } from '@react-navigation/native-stack';
@@ -39,10 +51,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -74,10 +85,11 @@ export default function App() {
-```js name="Native Stack Navigator" snack version=7
+```js name="Native Stack Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createNativeStackNavigator } from '@react-navigation/native-stack';
@@ -99,10 +111,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -137,19 +148,7 @@ If you encounter any bugs while using `createNativeStackNavigator`, please open
### Props
-The `Stack.Navigator` component accepts following props:
-
-#### `id`
-
-Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator.
-
-#### `initialRouteName`
-
-The name of the route to render on first load of the navigator.
-
-#### `screenOptions`
-
-Default options to use for the screens in the navigator.
+The native stack navigator accepts the [common props](navigator.md#configuration) shared by all navigators.
### Options
@@ -159,475 +158,551 @@ The following [options](screen-options.md) can be used to configure the screens
String that can be used as a fallback for `headerTitle`.
-#### `headerBackButtonMenuEnabled`
-
-Boolean indicating whether to show the menu on longPress of iOS >= 14 back button. Defaults to `true`.
-
-Requires `react-native-screens` version >=3.3.0.
-
-Only supported on iOS.
+#### `statusBarAnimation`
-#### `headerBackVisible`
+Sets the status bar animation (similar to the `StatusBar` component). Defaults to `fade` on iOS and `none` on Android.
-Whether the back button is visible in the header. You can use it to show a back button alongside `headerLeft` if you have specified it.
+Supported values:
-This will have no effect on the first screen in the stack.
+- `"fade"`
+- `"none"`
+- `"slide"`
-#### `headerBackTitle`
+On Android, setting either `fade` or `slide` will set the transition of status bar color. On iOS, this option applies to appereance animation of the status bar.
-Title string used by the back button on iOS. Defaults to the previous scene's title, or "Back" if there's not enough space. Use `headerBackTitleVisible: false` to hide it.
+Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
-Only supported on iOS.
+Only supported on Android and iOS.
-#### `headerBackTitleVisible`
+#### `statusBarHidden`
-Whether the back button title should be visible or not.
+Whether the status bar should be hidden on this screen.
-Only supported on iOS.
+Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
-#### `headerBackTitleStyle`
+Only supported on Android and iOS.
-Style object for header back title. Supported properties:
+#### `statusBarStyle`
-- `fontFamily`
-- `fontSize`
+Sets the status bar color (similar to the `StatusBar` component).
-Only supported on iOS.
+Supported values:
-#### `headerBackImageSource`
+- `"auto"` (iOS only)
+- `"inverted"` (iOS only)
+- `"dark"`
+- `"light"`
-Image to display in the header as the icon in the back button. Defaults to back icon image for the platform
+Defaults to `auto` on iOS and `light` on Android.
-- A chevron on iOS
-- An arrow on Android
+Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
-#### `headerLargeStyle`
+Only supported on Android and iOS.
-Style of the header when a large title is shown. The large title is shown if `headerLargeTitle` is `true` and the edge of any scrollable content reaches the matching edge of the header.
+#### `statusBarBackgroundColor`
-Supported properties:
+:::warning
-- backgroundColor
+This option is deprecated and will be removed in a future release (for apps targeting Android SDK 35 or above edge-to-edge mode is enabled by default
+and it is expected that the edge-to-edge will be enforced in future SDKs, see [here](https://developer.android.com/about/versions/15/behavior-changes-15#ux) for more information).
-Only supported on iOS.
+:::
-#### `headerLargeTitle`
+Sets the background color of the status bar (similar to the `StatusBar` component).
-Whether to enable header with large title which collapses to regular header on scroll.
+Only supported on Android.
-For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`. If the scrollable area doesn't fill the screen, the large title won't collapse on scroll. You also need to specify `contentInsetAdjustmentBehavior="automatic"` in your `ScrollView`, `FlatList` etc.
+#### `statusBarTranslucent`
-Only supported on iOS.
+:::warning
-#### `headerLargeTitleShadowVisible`
+This option is deprecated and will be removed in a future release (for apps targeting Android SDK 35 or above edge-to-edge mode is enabled by default
+and it is expected that the edge-to-edge will be enforced in future SDKs, see [here](https://developer.android.com/about/versions/15/behavior-changes-15#ux) for more information).
-Whether drop shadow of header is visible when a large title is shown.
+:::
-#### `headerLargeTitleStyle`
+Sets the translucency of the status bar (similar to the `StatusBar` component). Defaults to `false`.
-Style object for large title in header. Supported properties:
+Only supported on Android.
-- `fontFamily`
-- `fontSize`
-- `fontWeight`
-- `color`
+#### `contentStyle`
-Only supported on iOS.
+Style object for the scene content.
-#### `headerShown`
+#### `animationMatchesGesture`
-Whether to show the header. The header is shown by default. Setting this to `false` hides the header.
+Whether the gesture to dismiss should use animation provided to `animation` prop. Defaults to `false`.
-#### `headerStyle`
+Doesn't affect the behavior of screens presented modally.
-Style object for header. Supported properties:
+Only supported on iOS.
-- `backgroundColor`
+#### `fullScreenGestureEnabled`
-#### `headerShadowVisible`
+Whether the gesture to dismiss should work on the whole screen. Using gesture to dismiss with this option results in the same transition animation as `simple_push`. This behavior can be changed by setting `customAnimationOnGesture` prop. Achieving the default iOS animation isn't possible due to platform limitations. Defaults to `false`.
-Whether to hide the elevation shadow (Android) or the bottom border (iOS) on the header.
+Doesn't affect the behavior of screens presented modally.
-#### `headerTransparent`
+Only supported on iOS.
-Boolean indicating whether the navigation bar is translucent.
+#### `fullScreenGestureShadowEnabled`
-Defaults to `false`. Setting this to `true` makes the header absolutely positioned - so that the header floats over the screen so that it overlaps the content underneath, and changes the background color to `transparent` unless specified in `headerStyle`.
+Whether the full screen dismiss gesture has shadow under view during transition. Defaults to `true`.
-This is useful if you want to render a semi-transparent header or a blurred background.
+This does not affect the behavior of transitions that don't use gestures enabled by `fullScreenGestureEnabled` prop.
-Note that if you don't want your content to appear under the header, you need to manually add a top margin to your content. React Navigation won't do it automatically.
+#### `gestureEnabled`
-To get the height of the header, you can use [`HeaderHeightContext`](elements.md#headerheightcontext) with [React's Context API](https://reactjs.org/docs/context.html#contextconsumer) or [`useHeaderHeight`](elements.md#useheaderheight).
+Whether you can use gestures to dismiss this screen. Defaults to `true`. Only supported on iOS.
-#### `headerBlurEffect`
+#### `animationTypeForReplace`
-Blur effect for the translucent header. The `headerTransparent` option needs to be set to `true` for this to work.
+The type of animation to use when this screen replaces another screen. Defaults to `push`.
Supported values:
-- `extraLight`
-- `light`
-- `dark`
-- `regular`
-- `prominent`
-- `systemUltraThinMaterial`
-- `systemThinMaterial`
-- `systemMaterial`
-- `systemThickMaterial`
-- `systemChromeMaterial`
-- `systemUltraThinMaterialLight`
-- `systemThinMaterialLight`
-- `systemMaterialLight`
-- `systemThickMaterialLight`
-- `systemChromeMaterialLight`
-- `systemUltraThinMaterialDark`
-- `systemThinMaterialDark`
-- `systemMaterialDark`
-- `systemThickMaterialDark`
-- `systemChromeMaterialDark`
-
-Only supported on iOS.
+- `push`: the new screen will perform push animation.
-#### `headerBackground`
+
+
+
-Function which returns a React Element to render as the background of the header. This is useful for using backgrounds such as an image or a gradient.
+- `pop`: the new screen will perform pop animation.
-#### `headerTintColor`
+
+
+
-Tint color for the header. Changes the color of back button and title.
+#### `animation`
-#### `headerLeft`
+How the screen should animate when pushed or popped.
-Function which returns a React Element to display on the left side of the header. This replaces the back button. See `headerBackVisible` to show the back button along side left element.
+Only supported on Android and iOS.
-#### `headerRight`
+Supported values:
-Function which returns a React Element to display on the right side of the header.
+- `default`: use the platform default animation
+
+
+
-#### `headerTitle`
+- `fade`: fade screen in or out
+
+
+
-String or a function that returns a React Element to be used by the header. Defaults to `title` or name of the screen.
+- `fade_from_bottom`: fade the new screen from bottom
+
+
+
-When a function is passed, it receives `tintColor` and`children` in the options object as an argument. The title string is passed in `children`.
+- `flip`: flip the screen, requires `presentation: "modal"` (iOS only)
+
+
+
-Note that if you render a custom element by passing a function, animations for the title won't work.
+- `simple_push`: default animation, but without shadow and native header transition (iOS only, uses default animation on Android)
+
+
+
-#### `headerTitleAlign`
+- `slide_from_bottom`: slide in the new screen from bottom
+
+
+
-How to align the header title. Possible values:
+- `slide_from_right`: slide in the new screen from right (Android only, uses default animation on iOS)
+
+
+
-- `left`
-- `center`
+- `slide_from_left`: slide in the new screen from left (Android only, uses default animation on iOS)
+
+
+
-Defaults to `left` on platforms other than iOS.
+- `none`: don't animate the screen
+
+
+
-Not supported on iOS. It's always `center` on iOS and cannot be changed.
+#### `presentation`
-#### `headerTitleStyle`
+How should the screen be presented.
-Style object for header title. Supported properties:
+Only supported on Android and iOS.
-- `fontFamily`
-- `fontSize`
-- `fontWeight`
-- `color`
+Supported values:
-#### `headerSearchBarOptions`
+- `card`: the new screen will be pushed onto a stack, which means the default animation will be slide from the side on iOS, the animation on Android will vary depending on the OS version and theme.
+
+
+
-Options to render a native search bar on iOS. Search bars are rarely static so normally it is controlled by passing an object to `headerSearchBarOptions` navigation option in the component's body. You also need to specify `contentInsetAdjustmentBehavior="automatic"` in your `ScrollView`, `FlatList` etc. If you don't have a `ScrollView`, specify `headerTransparent: false`.
+- `modal`: the new screen will be presented modally. this also allows for a nested stack to be rendered inside the screen.
+
+
+
-Only supported on iOS and Android.
+- `transparentModal`: the new screen will be presented modally, but in addition, the previous screen will stay so that the content below can still be seen if the screen has translucent background.
+
+
+
-Example:
+- `containedModal`: will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to "modal" on Android.
+
+
+
-```js
-React.useLayoutEffect(() => {
- navigation.setOptions({
- headerSearchBarOptions: {
- // search bar options
- },
- });
-}, [navigation]);
-```
+- `containedTransparentModal`: will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to "transparentModal" on Android.
+
+
+
-Supported properties are described below.
+- `fullScreenModal`: will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to "modal" on Android. A screen using this presentation style can't be dismissed by gesture.
+
+
+
-##### `autoCapitalize`
+- `formSheet`: will use "BottomSheetBehavior" on Android and "UIModalPresentationFormSheet" modal style on iOS.
+
+
+
+
+
+
-Controls whether the text is automatically auto-capitalized as it is entered by the user.
-Possible values:
+##### Using Form Sheet
-- `none`
-- `words`
-- `sentences`
-- `characters`
+To use Form Sheet for your screen, add `presentation: 'formSheet'` to the `options`.
-Defaults to `sentences`.
+
+
-##### `autoFocus`
+```js name="Form Sheet" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
-Whether to automatically focus search bar when it's shown. Defaults to `false`.
+// codeblock-focus-start
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
-Only supported on Android.
+// codeblock-focus-end
-##### `barTintColor`
+function HomeScreen() {
+ const navigation = useNavigation();
-The search field background color. By default bar tint color is translucent.
+ return (
+
+ Home Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
-Only supported on iOS.
+function ProfileScreen() {
+ const navigation = useNavigation();
-##### `tintColor`
+ return (
+
+ Profile Screen
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam accumsan
+ euismod enim, quis porta ligula egestas sed. Maecenas vitae consequat
+ odio, at dignissim lorem. Ut euismod eros ac mi ultricies, vel pharetra
+ tortor commodo. Interdum et malesuada fames ac ante ipsum primis in
+ faucibus. Nullam at urna in metus iaculis aliquam at sed quam. In
+ ullamcorper, ex ut facilisis commodo, urna diam posuere urna, at
+ condimentum mi orci ac ipsum. In hac habitasse platea dictumst. Donec
+ congue pharetra ipsum in finibus. Nulla blandit finibus turpis, non
+ vulputate elit viverra a. Curabitur in laoreet nisl.
+
+ navigation.goBack()} style={{ marginTop: 15 }}>
+ Go back
+
+
+ );
+}
-The color for the cursor caret and cancel button text.
+// codeblock-focus-start
+const MyStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ },
+ Profile: {
+ screen: ProfileScreen,
+ options: {
+ presentation: 'formSheet',
+ headerShown: false,
+ sheetAllowedDetents: 'fitToContents',
+ },
+ },
+ },
+});
+// codeblock-focus-end
-Only supported on iOS.
+const Navigation = createStaticNavigation(MyStack);
-##### `cancelButtonText`
+export default function App() {
+ return ;
+}
+```
-The text to be used instead of default `Cancel` button text.
+
+
-Only supported on iOS.
+```js name="Form Sheet" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
-##### `disableBackButtonOverride`
+const Stack = createNativeStackNavigator();
-Whether the back button should close search bar's text input or not. Defaults to `false`.
+function MyStack() {
+ return (
+
+
+
+
+ );
+}
+// codeblock-focus-end
-Only supported on Android.
-
-##### `hideNavigationBar`
+function HomeScreen() {
+ const navigation = useNavigation();
-Boolean indicating whether to hide the navigation bar during searching. Defaults to `true`.
+ return (
+
+ Home Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
-Only supported on iOS.
+function ProfileScreen() {
+ const navigation = useNavigation();
-##### `hideWhenScrolling`
+ return (
+
+ Profile Screen
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam accumsan
+ euismod enim, quis porta ligula egestas sed. Maecenas vitae consequat
+ odio, at dignissim lorem. Ut euismod eros ac mi ultricies, vel pharetra
+ tortor commodo. Interdum et malesuada fames ac ante ipsum primis in
+ faucibus. Nullam at urna in metus iaculis aliquam at sed quam. In
+ ullamcorper, ex ut facilisis commodo, urna diam posuere urna, at
+ condimentum mi orci ac ipsum. In hac habitasse platea dictumst. Donec
+ congue pharetra ipsum in finibus. Nulla blandit finibus turpis, non
+ vulputate elit viverra a. Curabitur in laoreet nisl.
+
+ navigation.goBack()} style={{ marginTop: 15 }}>
+ Go back
+
+
+ );
+}
-Boolean indicating whether to hide the search bar when scrolling. Defaults to `true`.
+export default function App() {
+ return (
+
+
+
+ );
+}
+```
-Only supported on iOS.
+
+
-##### `inputType`
+:::warning
-The type of the input. Defaults to `"text"`.
+Due to technical issues in platform component integration with `react-native`, `presentation: 'formSheet'` has limited support for `flex: 1`.
-Supported values:
+On Android, using `flex: 1` on a top-level content container passed to a `formSheet` with `showAllowedDetents: 'fitToContents'` causes the sheet to not display at all, leaving only the dimmed background visible. This is because it is the sheet, not the parent who is source of the size. Setting fixed values for `sheetAllowedDetents`, e.g. `[0.4, 0.9]`, works correctly (content is aligned for the highest detent).
-- `"text"`
-- `"phone"`
-- `"number"`
-- `"email"`
+On iOS, `flex: 1` with `showAllowedDetents: 'fitToContents'` works properly but setting a fixed value for `showAllowedDetents` causes the screen to not respect the `flex: 1` style - the height of the container does not fill the `formSheet` fully, but rather inherits intrinsic size of its contents. This tradeoff is _currently_ necessary to prevent ["sheet flickering" problem on iOS](https://github.com/software-mansion/react-native-screens/issues/1722).
-Only supported on Android.
+If you don't use `flex: 1` but the content's height is less than max screen height, the rest of the sheet might become translucent or use the default theme background color (you can see this happening on the screenshots in the descrption of [this PR](https://github.com/software-mansion/react-native-screens/pull/2462)). To match the sheet to the background of your content, set `backgroundColor` in the `contentStyle` prop of the given screen.
-##### `obscureBackground`
+On Android, there are also some problems with getting nested ScrollViews to work properly. The solution is to set `nestedScrollEnabled` on the `ScrollView`, but this does not work if the content's height is less than the `ScrollView`'s height. Please see [this PR](https://github.com/facebook/react-native/pull/44099) for details and suggested [workaround](https://github.com/facebook/react-native/pull/44099#issuecomment-2058469661).
-Boolean indicating whether to obscure the underlying content with semi-transparent overlay. Defaults to `true`.
+On Android, nested stack and `headerShown` prop are not currently supported for screens with `presentation: 'formSheet'`.
-##### `placeholder`
+:::
-Text displayed when search field is empty.
+#### `sheetAllowedDetents`
-##### `textColor`
+:::note
-The color of the text in the search field.
+Works only when `presentation` is set to `formSheet`.
-##### `hintTextColor`
+:::
-The color of the hint text in the search field.
+
+
+
-Only supported on Android.
+Describes heights where a sheet can rest.
-##### `headerIconColor`
+Supported values:
-The color of the search and close icons shown in the header
+- `fitToContents` - intents to set the sheet height to the height of its contents.
+- Array of fractions, e.g. `[0.25, 0.5, 0.75]`:
+ - Heights should be described as fraction (a number from `[0, 1]` interval) of screen height / maximum detent height.
+ - The array **must** be sorted in ascending order. This invariant is verified only in developement mode, where violation results in error.
+ - iOS accepts any number of detents, while **Android is limited to three** - any surplus values, beside first three are ignored.
-Only supported on Android.
+Defaults to `[1.0]`.
-##### `shouldShowHintSearchIcon`
+Only supported on Android and iOS.
-Whether to show the search hint icon when search bar is focused. Defaults to `true`.
+#### `sheetElevation`
-Only supported on Android.
+:::note
-##### `onBlur`
+Works only when `presentation` is set to `formSheet`.
-A callback that gets called when search bar has lost focus.
+:::
-##### `onCancelButtonPress`
+
+
+
-A callback that gets called when the cancel button is pressed.
+Integer value describing elevation of the sheet, impacting shadow on the top edge of the sheet.
-##### `onChangeText`
+Not dynamic - changing it after the component is rendered won't have an effect.
-A callback that gets called when the text changes. It receives the current text value of the search bar.
+Defaults to `24`.
-Example:
+Only supported on Android.
-```js
-const [search, setSearch] = React.useState('');
+#### `sheetExpandsWhenScrolledToEdge`
-React.useLayoutEffect(() => {
- navigation.setOptions({
- headerSearchBarOptions: {
- onChangeText: (event) => setSearch(event.nativeEvent.text),
- },
- });
-}, [navigation]);
-```
+:::note
-#### `header`
+Works only when `presentation` is set to `formSheet`.
-Custom header to use instead of the default header.
+:::
-This accepts a function that returns a React Element to display as a header. The function receives an object containing the following properties as the argument:
+
+
+
-- `navigation` - The navigation object for the current screen.
-- `route` - The route object for the current screen.
-- `options` - The options for the current screen
-- `back` - Options for the back button, contains an object with a `title` property to use for back button label.
+Whether the sheet should expand to larger detent when scrolling.
-Example:
+Defaults to `true`.
-```js
-import { getHeaderTitle } from '@react-navigation/elements';
+Only supported on iOS.
-// ..
+:::warning
-header: ({ navigation, route, options, back }) => {
- const title = getHeaderTitle(options, route.name);
+Please note that for this interaction to work, the ScrollView must be "first-subview-chain" descendant of the Screen component. This restriction is due to platform requirements.
- return (
- : undefined
- }
- style={options.headerStyle}
- />
- );
-};
-```
+:::
-To set a custom header for all the screens in the navigator, you can specify this option in the `screenOptions` prop of the navigator.
+#### `sheetCornerRadius`
-Note that if you specify a custom header, the native functionality such as large title, search bar etc. won't work.
+:::note
-#### `statusBarAnimation`
+Works only when `presentation` is set to `formSheet`.
-Sets the status bar animation (similar to the `StatusBar` component). Defaults to `fade` on iOS and `none` on Android.
+:::
-Supported values:
+
+
+
-- `"fade"`
-- `"none"`
-- `"slide"`
+The corner radius that the sheet will try to render with.
-On Android, setting either `fade` or `slide` will set the transition of status bar color. On iOS, this option applies to appereance animation of the status bar.
+If set to non-negative value it will try to render sheet with provided radius, else it will apply system default.
-Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
+If left unset, system default is used.
Only supported on Android and iOS.
-#### `statusBarHidden`
+#### `sheetInitialDetentIndex`
-Whether the status bar should be hidden on this screen.
+:::note
-Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
+Works only when `presentation` is set to `formSheet`.
-Only supported on Android and iOS.
+:::
-#### `statusBarStyle`
+
+
+
-Sets the status bar color (similar to the `StatusBar` component). Defaults to `auto`.
+**Index** of the detent the sheet should expand to after being opened.
-Supported values:
+If the specified index is out of bounds of `sheetAllowedDetents` array, in dev environment more errors will be thrown, in production the value will be reset to default value.
-- `"auto"`
-- `"inverted"` (iOS only)
-- `"dark"`
-- `"light"`
+Additionaly there is `last` value available, when set the sheet will expand initially to last (largest) detent.
-Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file.
+Defaults to `0` - which represents first detent in the detents array.
Only supported on Android and iOS.
-#### `statusBarColor`
-
-Sets the status bar color (similar to the `StatusBar` component). Defaults to initial status bar color.
-
-Only supported on Android.
-
-#### `statusBarTranslucent`
-
-Sets the translucency of the status bar (similar to the `StatusBar` component). Defaults to `false`.
-
-Only supported on Android.
-
-#### `contentStyle`
-
-Style object for the scene content.
-
-#### `customAnimationOnGesture`
+#### `sheetGrabberVisible`
-Whether the gesture to dismiss should use animation provided to `animation` prop. Defaults to `false`.
+:::note
-Doesn't affect the behavior of screens presented modally.
+Works only when `presentation` is set to `formSheet`.
-Only supported on iOS.
+:::
-#### `fullScreenGestureEnabled`
+
+
+
-Whether the gesture to dismiss should work on the whole screen. Using gesture to dismiss with this option results in the same transition animation as `simple_push`. This behavior can be changed by setting `customAnimationOnGesture` prop. Achieving the default iOS animation isn't possible due to platform limitations. Defaults to `false`.
+Boolean indicating whether the sheet shows a grabber at the top.
-Doesn't affect the behavior of screens presented modally.
+Defaults to `false`.
Only supported on iOS.
-#### `gestureEnabled`
-
-Whether you can use gestures to dismiss this screen. Defaults to `true`. Only supported on iOS.
-
-#### `animationTypeForReplace`
-
-The type of animation to use when this screen replaces another screen. Defaults to `pop`.
+#### `sheetLargestUndimmedDetentIndex`
-Supported values:
-
-- `push`: the new screen will perform push animation.
-- `pop`: the new screen will perform pop animation.
+:::note
-#### `animation`
-
-How the screen should animate when pushed or popped.
+Works only when `presentation` is set to `formSheet`.
-Supported values:
+:::
-- `default`: use the platform default animation
-- `fade`: fade screen in or out
-- `fade_from_bottom`: fade the new screen from bottom
-- `flip`: flip the screen, requires `presentation: "modal"` (iOS only)
-- `simple_push`: default animation, but without shadow and native header transition (iOS only, uses default animation on Android)
-- `slide_from_bottom`: slide in the new screen from bottom
-- `slide_from_right`: slide in the new screen from right (Android only, uses default animation on iOS)
-- `slide_from_left`: slide in the new screen from left (Android only, uses default animation on iOS)
-- `none`: don't animate the screen
+
+
+
-Only supported on Android and iOS.
+The largest sheet detent for which a view underneath won't be dimmed.
-#### `presentation`
+This prop can be set to an number, which indicates index of detent in `sheetAllowedDetents` array for which there won't be a dimming view beneath the sheet.
-How should the screen be presented.
+Additionaly there are following options available:
-Supported values:
+- `none` - there will be dimming view for all detents levels,
+- `last` - there won't be a dimming view for any detent level.
-- `card`: the new screen will be pushed onto a stack, which means the default animation will be slide from the side on iOS, the animation on Android will vary depending on the OS version and theme.
-- `modal`: the new screen will be presented modally. this also allows for a nested stack to be rendered inside the screen.
-- `transparentModal`: the new screen will be presented modally, but in addition, the previous screen will stay so that the content below can still be seen if the screen has translucent background.
-- `containedModal`: will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to "modal" on Android.
-- `containedTransparentModal`: will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to "transparentModal" on Android.
-- `fullScreenModal`: will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to "modal" on Android. A screen using this presentation style can't be dismissed by gesture.
-- `formSheet`: will use "UIModalPresentationFormSheet" modal style on iOS and will fallback to "modal" on Android.
+Defaults to `none`, indicating that the dimming view should be always present.
Only supported on Android and iOS.
@@ -677,6 +752,13 @@ Only supported on iOS.
#### `navigationBarColor`
+:::warning
+
+This option is deprecated and will be removed in a future release (for apps targeting Android SDK 35 or above edge-to-edge mode is enabled by default
+and it is expected that the edge-to-edge will be enforced in future SDKs, see [here](https://developer.android.com/about/versions/15/behavior-changes-15#ux) for more information).
+
+:::
+
Sets the navigation bar color. Defaults to initial status bar color.
Only supported on Android.
@@ -692,94 +774,728 @@ Only supported on Android.
Boolean indicating whether to prevent inactive screens from re-rendering. Defaults to `false`.
Defaults to `true` when `enableFreeze()` from `react-native-screens` package is run at the top of the application.
-Requires `react-native-screens` version >=3.16.0.
-
Only supported on iOS and Android.
-### Events
+### Header related options
-The navigator can [emit events](navigation-events.md) on certain actions. Supported events are:
+The navigator supports following options to configure the header:
-#### `transitionStart`
+#### `headerBackButtonMenuEnabled`
-This event is fired when the transition animation starts for the current screen.
+Boolean indicating whether to show the menu on longPress of iOS >= 14 back button. Defaults to `true`.
-Event data:
+Only supported on iOS.
-- `e.data.closing` - Boolean indicating whether the screen is being opened or closed.
+
-Example:
+#### `headerBackVisible`
-```js
-React.useEffect(() => {
- const unsubscribe = navigation.addListener('transitionStart', (e) => {
- // Do something
- });
+Whether the back button is visible in the header. You can use it to show a back button alongside `headerLeft` if you have specified it.
- return unsubscribe;
-}, [navigation]);
-```
+This will have no effect on the first screen in the stack.
-#### `transitionEnd`
+#### `headerBackTitle`
-This event is fired when the transition animation ends for the current screen.
+Title string used by the back button on iOS. Defaults to the previous scene's title, "Back" or arrow icon depending on the available space. See `headerBackButtonDisplayMode` to read about limitations and customize the behavior.
-Event data:
+Use `headerBackButtonDisplayMode: "minimal"` to hide it.
-- `e.data.closing` - Boolean indicating whether the screen was opened or closed.
+Only supported on iOS.
-Example:
+
-```js
-React.useEffect(() => {
- const unsubscribe = navigation.addListener('transitionEnd', (e) => {
- // Do something
- });
+#### `headerBackButtonDisplayMode`
- return unsubscribe;
-}, [navigation]);
-```
+How the back button displays icon and title.
-### Helpers
+Supported values:
-The nativestack navigator adds the following methods to the navigation object:
+- "default" - Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
+- "generic" – Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon).
+- "minimal" – Always displays only the icon without a title.
-#### `replace`
+The space-aware behavior is disabled when:
-Replaces the current screen with a new screen in the stack. The method accepts the following arguments:
+- The iOS version is 13 or lower
+- Custom font family or size is set (e.g. with `headerBackTitleStyle`)
+- Back button menu is disabled (e.g. with `headerBackButtonMenuEnabled`)
-- `name` - _string_ - Name of the route to push onto the stack.
-- `params` - _object_ - Screen params to pass to the destination route.
+In such cases, a static title and icon are always displayed.
-```js
-navigation.replace('Profile', { owner: 'Michaś' });
-```
+Only supported on iOS.
-#### `push`
+#### `headerBackTitleStyle`
-Pushes a new screen to the top of the stack and navigate to it. The method accepts the following arguments:
+Style object for header back title. Supported properties:
-- `name` - _string_ - Name of the route to push onto the stack.
-- `params` - _object_ - Screen params to pass to the destination route.
+- `fontFamily`
+- `fontSize`
-```js
-navigation.push('Profile', { owner: 'Michaś' });
-```
+Only supported on iOS.
-#### `pop`
+
-Pops the current screen from the stack and navigates back to the previous screen. It takes one optional argument (`count`), which allows you to specify how many screens to pop back by.
+Example:
```js
-navigation.pop();
+ headerBackTitleStyle: {
+ fontSize: 14,
+ fontFamily: 'Georgia',
+ },
```
-#### `popTo`
+#### `headerBackImageSource`
-Navigates back to a previous screen in the stack by popping screens after it. The method accepts the following arguments:
+Image to display in the header as the icon in the back button. Defaults to back icon image for the platform
-- `name` - _string_ - Name of the route to navigate to.
-- `params` - _object_ - Screen params to pass to the destination route.
+- A chevron on iOS
+- An arrow on Android
+
+#### `headerLargeStyle`
+
+Style of the header when a large title is shown. The large title is shown if `headerLargeTitle` is `true` and the edge of any scrollable content reaches the matching edge of the header.
+
+Supported properties:
+
+- backgroundColor
+
+Only supported on iOS.
+
+
+
+
+
+
+#### `headerLargeTitle`
+
+Whether to enable header with large title which collapses to regular header on scroll.
+Defaults to `false`.
+
+For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`. If the scrollable area doesn't fill the screen, the large title won't collapse on scroll. You also need to specify `contentInsetAdjustmentBehavior="automatic"` in your `ScrollView`, `FlatList` etc.
+
+Only supported on iOS.
+
+
+
+
+
+
+#### `headerLargeTitleShadowVisible`
+
+Whether drop shadow of header is visible when a large title is shown.
+
+#### `headerLargeTitleStyle`
+
+Style object for large title in header. Supported properties:
+
+- `fontFamily`
+- `fontSize`
+- `fontWeight`
+- `color`
+
+Only supported on iOS.
+
+
+
+Example:
+
+```js
+ headerLargeTitleStyle: {
+ fontFamily: 'Georgia',
+ fontSize: 22,
+ fontWeight: '500',
+ color: 'blue',
+ },
+```
+
+#### `headerStyle`
+
+Style object for header. Supported properties:
+
+- `backgroundColor`
+
+
+
+
+
+
+#### `headerShadowVisible`
+
+Whether to hide the elevation shadow (Android) or the bottom border (iOS) on the header.
+
+Android:
+
+
+iOS:
+
+
+#### `headerTransparent`
+
+Boolean indicating whether the navigation bar is translucent.
+
+Defaults to `false`. Setting this to `true` makes the header absolutely positioned - so that the header floats over the screen so that it overlaps the content underneath, and changes the background color to `transparent` unless specified in `headerStyle`.
+
+This is useful if you want to render a semi-transparent header or a blurred background.
+
+Note that if you don't want your content to appear under the header, you need to manually add a top margin to your content. React Navigation won't do it automatically.
+
+To get the height of the header, you can use [`HeaderHeightContext`](elements.md#headerheightcontext) with [React's Context API](https://react.dev/reference/react/useContext#contextconsumer) or [`useHeaderHeight`](elements.md#useheaderheight).
+
+#### `headerBlurEffect`
+
+Blur effect for the translucent header. The `headerTransparent` option needs to be set to `true` for this to work.
+
+Supported values:
+
+- `extraLight`
+
+- `light`
+
+
+- `dark`
+
+
+- `regular`
+
+
+- `prominent`
+
+
+- `systemUltraThinMaterial`
+
+
+- `systemThinMaterial`
+
+
+- `systemMaterial`
+
+
+- `systemThickMaterial`
+
+
+- `systemChromeMaterial`
+
+
+- `systemUltraThinMaterialLight`
+
+
+- `systemThinMaterialLight`
+
+
+- `systemMaterialLight`
+
+
+- `systemThickMaterialLight`
+
+
+- `systemChromeMaterialLight`
+
+
+- `systemUltraThinMaterialDark`
+
+- `systemThinMaterialDark`
+
+
+- `systemMaterialDark`
+
+- `systemThickMaterialDark`
+
+
+- `systemChromeMaterialDark`
+
+
+Only supported on iOS.
+
+#### `headerBackground`
+
+Function which returns a React Element to render as the background of the header. This is useful for using backgrounds such as an image or a gradient.
+
+
+
+Example:
+
+```js
+ headerBackground: () => (
+
+ ),
+```
+
+#### `headerTintColor`
+
+Tint color for the header. Changes the color of back button and title.
+
+
+
+#### `headerLeft`
+
+Function which returns a React Element to display on the left side of the header. This replaces the back button. See `headerBackVisible` to show the back button along side left element. It receives the following properties in the arguments:
+
+- `tintColor` - The tint color to apply. Defaults to the [theme](themes.md)'s primary color.
+- `canGoBack` - Boolean indicating whether there is a screen to go back to.
+- `label` - Label text for the button. Usually the title of the previous screen.
+- `href` - The `href` to use for the anchor tag on web
+
+
+
+Example:
+
+```js
+ headerLeft: () => (
+
+ ),
+ headerBackVisible: true,
+ headerBackTitle: 'Back',
+```
+
+#### `unstable_headerLeftItems`
+
+:::warning
+
+This option is experimental and may change in a minor release.
+
+:::
+
+Function which returns an array of items to display as on the left side of the header. This will override `headerLeft` if both are specified. It receives the following properties in the arguments:
+
+- `tintColor` - The tint color to apply. Defaults to the [theme](themes.md)'s primary color.
+- `canGoBack` - Boolean indicating whether there is a screen to go back to.
+
+Example:
+
+```js
+unstable_headerRightItems: () => [
+ {
+ type: 'button',
+ title: 'Edit',
+ onPress: () => {
+ // Do something
+ },
+ },
+],
+```
+
+See [Header items](#header-items) for more information.
+
+Only supported on iOS.
+
+#### `headerRight`
+
+Function which returns a React Element to display on the right side of the header. It receives the following properties in the arguments:
+
+- `tintColor` - The tint color to apply. Defaults to the [theme](themes.md)'s primary color.
+- `canGoBack` - Boolean indicating whether there is a screen to go back to.
+
+
+
+Example:
+
+```js
+headerRight: () => ;
+```
+
+#### `unstable_headerRightItems`
+
+:::warning
+
+This option is experimental and may change in a minor release.
+
+:::
+
+Function which returns an array of items to display as on the right side of the header. This will override `headerRight` if both are specified. It receives the following properties in the arguments:
+
+- `tintColor` - The tint color to apply. Defaults to the [theme](themes.md)'s primary color.
+- `canGoBack` - Boolean indicating whether there is a screen to go back to.
+
+Example:
+
+```js
+unstable_headerRightItems: () => [
+ {
+ type: 'button',
+ title: 'Edit',
+ onPress: () => {
+ // Do something
+ },
+ },
+],
+```
+
+See [Header items](#header-items) for more information.
+
+Only supported on iOS.
+
+#### `headerTitle`
+
+String or a function that returns a React Element to be used by the header. Defaults to `title` or name of the screen.
+
+When a function is passed, it receives `tintColor` and`children` in the options object as an argument. The title string is passed in `children`.
+
+Note that if you render a custom element by passing a function, animations for the title won't work.
+
+#### `headerTitleAlign`
+
+How to align the header title. Possible values:
+
+- `left`
+
+
+- `center`
+
+
+Defaults to `left` on platforms other than iOS.
+
+Not supported on iOS. It's always `center` on iOS and cannot be changed.
+
+#### `headerTitleStyle`
+
+Style object for header title. Supported properties:
+
+- `fontFamily`
+- `fontSize`
+- `fontWeight`
+- `color`
+
+
+
+Example:
+
+```js
+ headerTitleStyle: {
+ color: 'blue',
+ fontSize: 22,
+ fontFamily: 'Georgia',
+ fontWeight: 300,
+ },
+```
+
+#### `headerSearchBarOptions`
+
+Options to render a native search bar. Search bars are rarely static so normally it is controlled by passing an object to `headerSearchBarOptions` navigation option in the component's body.
+
+On iOS, you also need to specify `contentInsetAdjustmentBehavior="automatic"` in your `ScrollView`, `FlatList` etc. If you don't have a `ScrollView`, specify `headerTransparent: false`.
+
+Example:
+
+```js
+React.useLayoutEffect(() => {
+ navigation.setOptions({
+ headerSearchBarOptions: {
+ // search bar options
+ },
+ });
+}, [navigation]);
+```
+
+Supported properties are:
+
+##### `ref`
+
+Ref to manipulate the search input imperatively. It contains the following methods:
+
+- `focus` - focuses the search bar
+- `blur` - removes focus from the search bar
+- `setText` - sets the search bar's content to given value
+- `clearText` - removes any text present in the search bar input field
+- `cancelSearch` - cancel the search and close the search bar
+- `toggleCancelButton` - depending on passed boolean value, hides or shows cancel button (only supported on iOS)
+
+##### `autoCapitalize`
+
+Controls whether the text is automatically auto-capitalized as it is entered by the user.
+Possible values:
+
+- `systemDefault`
+- `none`
+- `words`
+- `sentences`
+- `characters`
+
+Defaults to `systemDefault` which is the same as `sentences` on iOS and `none` on Android.
+
+##### `autoFocus`
+
+Whether to automatically focus search bar when it's shown. Defaults to `false`.
+
+Only supported on Android.
+
+##### `barTintColor`
+
+The search field background color. By default bar tint color is translucent.
+
+Only supported on iOS.
+
+
+
+##### `tintColor`
+
+The color for the cursor caret and cancel button text.
+
+Only supported on iOS.
+
+
+
+##### `cancelButtonText`
+
+The text to be used instead of default `Cancel` button text.
+
+Only supported on iOS. **Deprecated** starting from iOS 26.
+
+##### `disableBackButtonOverride`
+
+Whether the back button should close search bar's text input or not. Defaults to `false`.
+
+Only supported on Android.
+
+##### `hideNavigationBar`
+
+Boolean indicating whether to hide the navigation bar during searching.
+
+If left unset, system default is used.
+
+Only supported on iOS.
+
+##### `hideWhenScrolling`
+
+Boolean indicating whether to hide the search bar when scrolling. Defaults to `true`.
+
+Only supported on iOS.
+
+##### `inputType`
+
+The type of the input. Defaults to `"text"`.
+
+Supported values:
+
+- `"text"`
+- `"phone"`
+- `"number"`
+- `"email"`
+
+Only supported on Android.
+
+##### `obscureBackground`
+
+Boolean indicating whether to obscure the underlying content with semi-transparent overlay.
+
+If left unset, system default is used.
+
+Only supported on iOS.
+
+##### `placement`
+
+Controls preferred placement of the search bar. Defaults to `automatic`.
+
+Supported values:
+
+- `automatic`
+- `stacked`
+- `inline` (**deprecated** starting from iOS 26, it is mapped to `integrated`)
+- `integrated` (available starting from iOS 26, on prior versions it is mapped to `inline`)
+- `integratedButton` (available starting from iOS 26, on prior versions it is mapped to `inline`)
+- `integratedCentered` (available starting from iOS 26, on prior versions it is mapped to `inline`)
+
+Only supported on iOS.
+
+##### `allowToolbarIntegration`
+
+Boolean indicating whether the system can place the search bar among other toolbar items on iPhone.
+
+Set this prop to `false` to prevent the search bar from appearing in the toolbar when `placement` is `automatic`, `integrated`, `integratedButton` or `integratedCentered`.
+
+Defaults to `true`. If `placement` is set to `stacked`, the value of this prop will be overridden with `false`.
+
+Only supported on iOS, starting from iOS 26.
+
+##### `placeholder`
+
+Text displayed when search field is empty.
+
+##### `textColor`
+
+The color of the text in the search field.
+
+
+
+##### `hintTextColor`
+
+The color of the hint text in the search field.
+
+Only supported on Android.
+
+
+
+##### `headerIconColor`
+
+The color of the search and close icons shown in the header
+
+Only supported on Android.
+
+
+
+##### `shouldShowHintSearchIcon`
+
+Whether to show the search hint icon when search bar is focused. Defaults to `true`.
+
+Only supported on Android.
+
+##### `onBlur`
+
+A callback that gets called when search bar has lost focus.
+
+##### `onCancelButtonPress`
+
+A callback that gets called when the cancel button is pressed.
+
+##### `onChangeText`
+
+A callback that gets called when the text changes. It receives the current text value of the search bar.
+
+Example:
+
+```js
+const [search, setSearch] = React.useState('');
+
+React.useLayoutEffect(() => {
+ navigation.setOptions({
+ headerSearchBarOptions: {
+ onChangeText: (event) => setSearch(event.nativeEvent.text),
+ },
+ });
+}, [navigation]);
+```
+
+#### `headerShown`
+
+Whether to show the header. The header is shown by default. Setting this to `false` hides the header.
+
+#### `header`
+
+Custom header to use instead of the default header.
+
+This accepts a function that returns a React Element to display as a header. The function receives an object containing the following properties as the argument:
+
+- `navigation` - The navigation object for the current screen.
+- `route` - The route object for the current screen.
+- `options` - The options for the current screen
+- `back` - Options for the back button, contains an object with a `title` property to use for back button label.
+
+Example:
+
+```js
+import { getHeaderTitle } from '@react-navigation/elements';
+
+// ..
+
+header: ({ navigation, route, options, back }) => {
+ const title = getHeaderTitle(options, route.name);
+
+ return (
+ : undefined
+ }
+ style={options.headerStyle}
+ />
+ );
+};
+```
+
+To set a custom header for all the screens in the navigator, you can specify this option in the `screenOptions` prop of the navigator.
+
+Note that if you specify a custom header, the native functionality such as large title, search bar etc. won't work.
+
+### Events
+
+The navigator can [emit events](navigation-events.md) on certain actions. Supported events are:
+
+#### `transitionStart`
+
+This event is fired when the transition animation starts for the current screen.
+
+Event data:
+
+- `e.data.closing` - Boolean indicating whether the screen is being opened or closed.
+
+Example:
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('transitionStart', (e) => {
+ // Do something
+ });
+
+ return unsubscribe;
+}, [navigation]);
+```
+
+#### `transitionEnd`
+
+This event is fired when the transition animation ends for the current screen.
+
+Event data:
+
+- `e.data.closing` - Boolean indicating whether the screen was opened or closed.
+
+Example:
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('transitionEnd', (e) => {
+ // Do something
+ });
+
+ return unsubscribe;
+}, [navigation]);
+```
+
+### Helpers
+
+The native stack navigator adds the following methods to the navigation object:
+
+#### `replace`
+
+Replaces the current screen with a new screen in the stack. The method accepts the following arguments:
+
+- `name` - _string_ - Name of the route to push onto the stack.
+- `params` - _object_ - Screen params to pass to the destination route.
+
+```js
+navigation.replace('Profile', { owner: 'Michaś' });
+```
+
+#### `push`
+
+Pushes a new screen to the top of the stack and navigate to it. The method accepts the following arguments:
+
+- `name` - _string_ - Name of the route to push onto the stack.
+- `params` - _object_ - Screen params to pass to the destination route.
+
+```js
+navigation.push('Profile', { owner: 'Michaś' });
+```
+
+#### `pop`
+
+Pops the current screen from the stack and navigates back to the previous screen. It takes one optional argument (`count`), which allows you to specify how many screens to pop back by.
+
+```js
+navigation.pop();
+```
+
+#### `popTo`
+
+Navigates back to a previous screen in the stack by popping screens after it. The method accepts the following arguments:
+
+- `name` - _string_ - Name of the route to navigate to.
+- `params` - _object_ - Screen params to pass to the destination route.
+- `options` - Options object containing the following properties:
+ - `merge` - _boolean_ - Whether params should be merged with the existing route params, or replace them (when navigating to an existing screen). Defaults to `false`.
If a matching screen is not found in the stack, this will pop the current screen and add a new screen with the specified name and params.
@@ -795,44 +1511,267 @@ Pops all of the screens in the stack except the first one and navigates to it.
navigation.popToTop();
```
-## Example
+### Hooks
+
+The native stack navigator exports the following hooks:
+
+#### `useAnimatedHeaderHeight`
+
+The hook returns an animated value representing the height of the header. This is similar to [`useHeaderHeight`](elements.md#useheaderheight) but returns an animated value that changed as the header height changes, e.g. when expanding or collapsing large title or search bar on iOS.
+
+It can be used to animated content along with header height changes.
```js
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Animated } from 'react-native';
+import { useAnimatedHeaderHeight } from '@react-navigation/native-stack';
-const Stack = createNativeStackNavigator();
+const MyView = () => {
+ const headerHeight = useAnimatedHeaderHeight();
-function MyStack() {
return (
-
-
-
-
-
+ />
);
-}
+};
+```
+
+## Header items
+
+The [`unstable_headerLeftItems`](#unstable_headerleftitems) and [`unstable_headerRightItems`](#unstable_headerrightitems) options allow you to add header items to the left and right side of the header respectively. This items can show native buttons, menus or custom React elements.
+
+On iOS 26+, the header right items can also be collapsed into an overflow menu by the system when there is not enough space to show all items. Note that custom elements (with `type: 'custom'`) won't be collapsed into the overflow menu.
+
+
+
+
+
+There are 3 categories of items that can be displayed in the header:
+
+### Action
+
+A regular button that performs an action when pressed, or shows a menu.
+
+Common properties:
+
+- `type`: Must be `button` or `menu`.
+- `label`: Label of the item. The label is not shown if `icon` is specified. However, it is used by screen readers, or if the header items get collapsed due to lack of space.
+- `labelStyle`: Style object for the label. Supported properties:
+ - `fontFamily`
+ - `fontSize`
+ - `fontWeight`
+ - `color`
+- `icon`: Optional icon to show instead of the label.
+
+ The icon can be an image:
+
+ ```js
+ {
+ type: 'image',
+ source: require('./path/to/image.png'),
+ }
+ ```
+
+ Or a [SF Symbols](https://developer.apple.com/sf-symbols/) name:
+
+ ```js
+ {
+ type: 'sfSymbol',
+ name: 'heart',
+ }
+ ```
+
+- `variant`: Visual variant of the button. Supported values:
+ - `plain` (default)
+ - `done`
+ - `prominent`
+- `tintColor`: Tint color to apply to the item.
+- `disabled`: Whether the item is disabled.
+- `width`: Width of the item.
+- `hidesSharedBackground` (iOS 26+): Whether the background this item may share with other items should be hidden. Setting this to `true` hides the liquid glass background.
+- `sharesBackground` (iOS 26+): Whether this item can share a background with other items.
+- `identifier` (iOS 26+) - An identifier used to match items across transitions.
+- `badge` (iOS 26+): An optional badge to display alongside the item. Supported properties:
+ - `value`: The value to display in the badge. It can be a string or a number.
+ - `style`: Style object for the badge. Supported properties:
+ - `fontFamily`
+ - `fontSize`
+ - `fontWeight`
+ - `color`
+- `accessibilityLabel`: Accessibility label for the item.
+- `accessibilityHint`: Accessibility hint for the item.
+
+Supported properties when `type` is `button`:
+
+- `onPress`: Function to call when the button is pressed.
+- `selected`: Whether the button is in a selected state.
+
+Example:
+
+```js
+unstable_headerRightItems: () => [
+ {
+ type: 'button',
+ label: 'Edit',
+ icon: {
+ type: 'sfSymbol',
+ name: 'pencil',
+ },
+ onPress: () => {
+ // Do something
+ },
+ },
+],
+```
+
+Supported properties when `type` is `menu`:
+
+- `changesSelectionAsPrimaryAction`: Whether the menu is a selection menu. Tapping an item in a selection menu will add a checkmark to the selected item. Defaults to `false`.
+- `menu`: An object containing the menu items. It contains the following properties:
+
+ - `title`: Optional title to show on top of the menu.
+ - `items`: An array of menu items. A menu item can be either an `action` or a `submenu`.
+
+ - `action`: An object with the following properties:
+
+ - `type`: Must be `action`.
+ - `label`: Label of the menu item.
+ - `icon`: Optional icon to show alongside the label. The icon can be a [SF Symbols](https://developer.apple.com/sf-symbols/) name:
+
+ ```js
+ {
+ type: 'sfSymbol',
+ name: 'trash',
+ }
+ ```
+
+ - `onPress`: Function to call when the menu item is pressed.
+ - `state`: Optional state of the menu item. Supported values:
+ - `on`
+ - `off`
+ - `mixed`
+ - `disabled`: Whether the menu item is disabled.
+ - `destructive`: Whether the menu item is styled as destructive.
+ - `hidden`: Whether the menu item is hidden.
+ - `keepsMenuPresented`: Whether to keep the menu open after selecting this item. Defaults to `false`.
+ - `discoverabilityLabel`: An elaborated title that explains the purpose of the action.
+
+ - `submenu`: An object with the following properties:
+
+ - `type`: Must be `submenu`.
+ - `label`: Label of the submenu item.
+ - `icon`: Optional icon to show alongside the label. The icon can be a [SF Symbols](https://developer.apple.com/sf-symbols/) name:
+
+ ```js
+ {
+ type: 'sfSymbol',
+ name: 'pencil',
+ }
+ ```
+
+ - `items`: An array of menu items (can be either `action` or `submenu`).
+
+Example:
+
+```js
+unstable_headerRightItems: () => [
+ {
+ type: 'menu',
+ label: 'Options',
+ icon: {
+ type: 'sfSymbol',
+ name: 'ellipsis',
+ },
+ menu: {
+ title: 'Options',
+ items: [
+ {
+ type: 'action',
+ label: 'Edit',
+ icon: {
+ type: 'sfSymbol',
+ name: 'pencil',
+ },
+ onPress: () => {
+ // Do something
+ },
+ },
+ {
+ type: 'submenu',
+ label: 'More',
+ items: [
+ {
+ type: 'action',
+ label: 'Delete',
+ destructive: true,
+ onPress: () => {
+ // Do something
+ },
+ },
+ ],
+ },
+ ],
+ },
+ },
+],
+```
+
+### Spacing
+
+An item to add spacing between other items in the header.
+
+Supported properties:
+
+- `type`: Must be `spacing`.
+- `spacing`: Amount of spacing to add.
+
+```js
+unstable_headerRightItems: () => [
+ {
+ type: 'button',
+ label: 'Edit',
+ onPress: () => {
+ // Do something
+ },
+ },
+ {
+ type: 'spacing',
+ spacing: 10,
+ },
+ {
+ type: 'button',
+ label: 'Delete',
+ onPress: () => {
+ // Do something
+ },
+ },
+],
+```
+
+### Custom
+
+A custom item to display any React Element in the header.
+
+Supported properties:
+
+- `type`: Must be `custom`.
+- `element`: A React Element to display as the item.
+- `hidesSharedBackground`: Whether the background this item may share with other items in the bar should be hidden. Setting this to `true` hides the liquid glass background on iOS 26+.
+
+Example:
+
+```js
+unstable_headerRightItems: () => [
+ {
+ type: 'custom',
+ element: ,
+ },
+],
```
+
+The advantage of using this over [`headerLeft`](#headerleft) or [`headerRight`](#headerright) options is that it supports features like shared background on iOS 26+.
diff --git a/versioned_docs/version-7.x/navigating-without-navigation-prop.md b/versioned_docs/version-7.x/navigating-without-navigation-prop.md
index e5c1fa10822..0200c83209a 100755
--- a/versioned_docs/version-7.x/navigating-without-navigation-prop.md
+++ b/versioned_docs/version-7.x/navigating-without-navigation-prop.md
@@ -1,16 +1,19 @@
---
id: navigating-without-navigation-prop
title: Navigating without the navigation prop
-sidebar_label: Navigating without the navigation prop
+sidebar_label: Navigation Ref
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Sometimes you need to trigger a navigation action from places where you do not have access to the `navigation` object, such as a Redux middleware. For such cases, you can dispatch navigation actions use a [`ref` on the navigation container](navigation-container.md#ref).
**Do not** use the `ref` if:
- You need to navigate from inside a component without needing to pass the `navigation` prop down, see [`useNavigation`](use-navigation.md) instead. The `ref` behaves differently, and many helper methods specific to screens aren't available.
- You need to handle deep links or universal links. Doing this with the `ref` has many edge cases. See [configuring links](configuring-links.md) for more information on handling deep linking.
-- You need to integrate with third party libraries, such as push notifications, branch etc. See [third party integrations for deep linking](deep-linking.md#third-party-integrations) instead.
+- You need to integrate with third party libraries, such as push notifications, branch etc. See [Integrating with other tools](deep-linking.md#integrating-with-other-tools) instead.
**Do** use the `ref` if:
@@ -22,9 +25,26 @@ Note that it's usually better to trigger navigation from user actions such as bu
You can get access to the root navigation object through a `ref` and pass it to the `RootNavigation` which we will later use to navigate.
+
+
+
```js
-// App.js
+import { createStaticNavigation } from '@react-navigation/native';
+import { navigationRef } from './RootNavigation';
+
+/* ... */
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js
import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';
@@ -35,6 +55,9 @@ export default function App() {
}
```
+
+
+
In the next step, we define `RootNavigation`, which is a simple module with functions that dispatch user-defined navigation actions.
```js
@@ -42,7 +65,7 @@ In the next step, we define `RootNavigation`, which is a simple module with func
import { createNavigationContainerRef } from '@react-navigation/native';
-export const navigationRef = createNavigationContainerRef()
+export const navigationRef = createNavigationContainerRef();
export function navigate(name, params) {
if (navigationRef.isReady()) {
@@ -55,17 +78,135 @@ export function navigate(name, params) {
Then, in any of your javascript modules, import the `RootNavigation` and call functions which you exported from it. You may use this approach outside of your React components and, in fact, it works as well when used from within them.
-
+
+
-```js
-// any js module
-import * as RootNavigation from './path/to/RootNavigation.js';
+```js name="Using navigate in any js module" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ createNavigationContainerRef,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+const navigationRef = createNavigationContainerRef();
+
+// codeblock-focus-start
+function navigate(name, params) {
+ if (navigationRef.isReady()) {
+ navigationRef.navigate(name, params);
+ }
+}
+
+// Example of usage in any of js modules
+//import * as RootNavigation from './path/to/RootNavigation.js';
+
+// ...
+
+// RootNavigation.navigate('ChatScreen', { userName: 'Lucy' });
+
+function Home() {
+ return (
+
+ navigate('Settings', { userName: 'Lucy' })}>
+ Go to Settings
+
+
+ );
+}
+// codeblock-focus-end
+
+function Settings({ route }) {
+ return (
+
+ Hello {route.params.userName}
+ navigate('Home')}>Go to Home
+
+ );
+}
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: Home,
+ Settings: Settings,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Using navigate in any js module" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ createNavigationContainerRef,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+const navigationRef = createNavigationContainerRef();
+
+// codeblock-focus-start
+function navigate(name, params) {
+ if (navigationRef.isReady()) {
+ navigationRef.navigate(name, params);
+ }
+}
+
+// Example of usage in any of js modules
+//import * as RootNavigation from './path/to/RootNavigation.js';
// ...
-RootNavigation.navigate('ChatScreen', { userName: 'Lucy' });
+// RootNavigation.navigate('ChatScreen', { userName: 'Lucy' });
+
+function Home() {
+ return (
+
+ navigate('Settings', { userName: 'Lucy' })}>
+ Go to Settings
+
+
+ );
+}
+// codeblock-focus-end
+
+function Settings({ route }) {
+ return (
+
+ Hello {route.params.userName}
+ navigate('Home')}>Go to Home
+
+ );
+}
+
+const RootStack = createNativeStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
Apart from `navigate`, you can add other navigation actions:
```js
@@ -97,16 +238,82 @@ For an example, consider the following scenario, you have a screen somewhere in
To avoid this, you can use the `isReady()` method available on the ref as shown in the above examples.
-
-
-```js
-// RootNavigation.js
+
+
+```js name="Handling navigation init" snack
import * as React from 'react';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ createNavigationContainerRef,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+const navigationRef = createNavigationContainerRef();
+
+function navigate(name, params) {
+ if (navigationRef.isReady()) {
+ // Perform navigation if the react navigation is ready to handle actions
+ navigationRef.navigate(name, params);
+ } else {
+ // You can decide what to do if react navigation is not ready
+ // You can ignore this, or add these actions to a queue you can call later
+ }
+}
+// codeblock-focus-end
-export const navigationRef = createNavigationContainerRef()
+function Home() {
+ return (
+
+ Home
+ navigate('Profile')}>Go to Profile
+
+ );
+}
-export function navigate(name, params) {
+function Profile() {
+ return (
+
+ Profile
+
+ );
+}
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: Home,
+ Profile: Profile,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Handling navigation init" snack
+import * as React from 'react';
+import { Text, View } from 'react-native';
+import {
+ NavigationContainer,
+ createNavigationContainerRef,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+const Stack = createNativeStackNavigator();
+// codeblock-focus-start
+const navigationRef = createNavigationContainerRef();
+
+function navigate(name, params) {
if (navigationRef.isReady()) {
// Perform navigation if the react navigation is ready to handle actions
navigationRef.navigate(name, params);
@@ -115,6 +322,38 @@ export function navigate(name, params) {
// You can ignore this, or add these actions to a queue you can call later
}
}
+// codeblock-focus-end
+
+function Home() {
+ return (
+
+ Home
+ navigate('Profile')}>Go to Profile
+
+ );
+}
+
+function Profile() {
+ return (
+
+ Profile
+
+ );
+}
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
If you're unsure if a navigator is rendered, you can call `navigationRef.current.getRootState()`, and it'll return a valid state object if any navigators are rendered, otherwise it will return `undefined`.
diff --git a/versioned_docs/version-7.x/navigating.md b/versioned_docs/version-7.x/navigating.md
index 9a8ccd30d43..73057ef5193 100755
--- a/versioned_docs/version-7.x/navigating.md
+++ b/versioned_docs/version-7.x/navigating.md
@@ -28,26 +28,29 @@ We'll do something similar to the latter, but rather than using a `window.locati
## Navigating to a new screen
-```js name="Navigating to a new screen" snack version=7
+```js name="Navigating to a new screen" snack
// codeblock-focus-start
import * as React from 'react';
-import { Button, View, Text } from 'react-native';
+import { View, Text } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
+ // highlight-next-line
const navigation = useNavigation();
return (
Home Screen
- navigation.navigate('Details')}
- />
+ // highlight-start
+ navigation.navigate('Details')}>
+ Go to Details
+
+ // highlight-end
);
}
@@ -78,6 +81,10 @@ export default function App() {
}
```
+
+
+
+
Let's break this down:
- `navigation` - the `navigation` object is returned from the [`useNavigation`](use-navigation.md) hook (more about this later in ["The navigation object in depth"](navigation-object.md)).
@@ -93,14 +100,15 @@ So we now have a stack with two routes: 1) the `Home` route 2) the `Details` rou
## Navigate to a screen multiple times
-```js name="Navigate to a screen multiple times" snack version=7
+```js name="Navigate to a screen multiple times" snack
import * as React from 'react';
-import { Button, View, Text } from 'react-native';
+import { View, Text } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -108,10 +116,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -123,10 +130,11 @@ function DetailsScreen() {
return (
Details Screen
- navigation.navigate('Details')}
- />
+ // highlight-start
+ navigation.navigate('Details')}>
+ Go to Details... again
+
+ // highlight-end
);
}
@@ -151,14 +159,15 @@ If you run this code, you'll notice that when you tap "Go to Details... again",
Let's suppose that we actually _want_ to add another details screen. This is pretty common in cases where you pass in some unique data to each route (more on that later when we talk about `params`!). To do this, we can change `navigate` to `push`. This allows us to express the intent to add another route regardless of the existing navigation history.
-```js name="Navigate to a screen multiple times" snack version=7
+```js name="Navigate to a screen multiple times" snack
import * as React from 'react';
-import { Button, View, Text } from 'react-native';
+import { View, Text } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -166,10 +175,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -181,10 +189,9 @@ function DetailsScreen() {
Details Screen
// codeblock-focus-start
- navigation.push('Details')}
- />
+ navigation.push('Details')}>
+ Go to Details... again
+
// codeblock-focus-end
);
@@ -205,13 +212,11 @@ export default function App() {
}
```
-
-
-
-
-
+
+
+
-Each time you call `push` we add a new route to the navigation stack. When you call `navigate` it first tries to find an existing route with that name, and only pushes a new route if there isn't yet one on the stack.
+Each time you call `push` we add a new route to the navigation stack. When you call `navigate` it only pushes a new route if you're not already on that route.
## Going back
@@ -219,14 +224,15 @@ The header provided by the native stack navigator will automatically include a b
Sometimes you'll want to be able to programmatically trigger this behavior, and for that, you can use `navigation.goBack()`.
-```js name="Going back" snack version=7
+```js name="Going back" snack
import * as React from 'react';
-import { Button, View, Text } from 'react-native';
+import { View, Text } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -234,10 +240,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -249,12 +254,11 @@ function DetailsScreen() {
return (
Details Screen
- navigation.push('Details')}
- />
+ navigation.push('Details')}>
+ Go to Details... again
+
// highlight-start
- navigation.goBack()} />
+ navigation.goBack()}>Go back
// highlight-end
);
@@ -276,6 +280,10 @@ export default function App() {
}
```
+
+
+
+
:::note
On Android, React Navigation hooks in to the hardware back button and fires the `goBack()` function for you when the user presses it, so it behaves as the user would expect.
@@ -284,14 +292,15 @@ On Android, React Navigation hooks in to the hardware back button and fires the
Another common requirement is to be able to go back _multiple_ screens -- for example, if you are several screens deep in a stack and want to dismiss all of them to go back to the first screen. In this case, we know that we want to go back to `Home` so we can use `popTo('Home')`. Another alternative would be `navigation.popToTop()`, which goes back to the first screen in the stack.
-```js name="Going back to specific screen" snack version=7
+```js name="Going back to specific screen" snack
import * as React from 'react';
-import { Button, View, Text } from 'react-native';
+import { View, Text } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -299,10 +308,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -314,17 +322,15 @@ function DetailsScreen() {
return (
Details Screen
- navigation.push('Details')}
- />
- navigation.goBack()} />
+ navigation.push('Details')}>
+ Go to Details... again
+
+ navigation.goBack()}>Go back
// highlight-start
- navigation.popTo('Home')} />
- navigation.popToTop()}
- />
+ navigation.popTo('Home')}>Go to Home
+ navigation.popToTop()}>
+ Go back to first screen in stack
+
// highlight-end
);
@@ -346,10 +352,14 @@ export default function App() {
}
```
+
+
+
+
## Summary
-- `navigation.navigate('RouteName')` pushes a new route to the native stack navigator if it's not already in the stack, otherwise it jumps to that screen.
-- We can call `navigation.push('RouteName')` as many times as we like and it will continue pushing routes.
-- The header bar will automatically show a back button, but you can programmatically go back by calling `navigation.goBack()`. On Android, the hardware back button just works as expected.
-- You can go back to an existing screen in the stack with `navigation.popTo('RouteName')`, and you can go back to the first screen in the stack with `navigation.popToTop()`.
-- The `navigation` object is available to all screen components with the [`useNavigation`](use-navigation.md) hook.
+- [`navigation.navigate('RouteName')`](navigation-object.md#navigate) pushes a new route to the native stack navigator if you're not already on that route.
+- We can call [`navigation.push('RouteName')`](stack-actions.md#push) as many times as we like and it will continue pushing routes.
+- The header bar will automatically show a back button, but you can programmatically go back by calling [`navigation.goBack()`](navigation-object.md#goback). On Android, the hardware back button just works as expected.
+- You can go back to an existing screen in the stack with [`navigation.popTo('RouteName')`](stack-actions.md#popto), and you can go back to the first screen in the stack with [`navigation.popToTop()`](stack-actions.md#poptotop).
+- The [`navigation`](navigation-object.md) object is available to all screen components with the [`useNavigation`](use-navigation.md) hook.
diff --git a/versioned_docs/version-7.x/navigation-actions.md b/versioned_docs/version-7.x/navigation-actions.md
index 2e60168b3f6..91b6dfa41fc 100755
--- a/versioned_docs/version-7.x/navigation-actions.md
+++ b/versioned_docs/version-7.x/navigation-actions.md
@@ -4,11 +4,14 @@ title: CommonActions reference
sidebar_label: CommonActions
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
A navigation action is an object containing at least a `type` property. Internally, the action can be handled by [routers](custom-routers.md) with the `getStateForAction` method to return a new state from an existing [navigation state](navigation-state.md).
Each navigation actions can contain at least the following properties:
-- `type` (required) - A string which represents the name of the action.
+- `type` (required) - A string that represents the name of the action.
- `payload` (options) - An object containing additional information about the action. For example, it will contain `name` and `params` for `navigate`.
- `source` (optional) - The key of the route which should be considered as the source of the action. This is used for some actions to determine which route to apply the action on. By default, `navigation.dispatch` adds the key of the route that dispatched the action.
- `target` (optional) - The key of the [navigation state](navigation-state.md) the action should be applied on.
@@ -25,60 +28,373 @@ The `navigate` action allows to navigate to a specific route. It takes the follo
- `name` - _string_ - A destination name of the screen in the current or a parent navigator.
- `params` - _object_ - Params to use for the destination route.
+- `options` - Options object containing the following properties:
+ - `merge` - _boolean_ - Whether params should be merged with the existing route params, or replace them (when navigating to an existing screen). Defaults to `false`.
+ - `pop` - _boolean_ - Whether screens should be popped to navigate to a matching screen in the stack. Defaults to `false`.
-
+
+
-```js
-import { CommonActions } from '@react-navigation/native';
+```js name="Common actions navigate" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
-navigation.dispatch(
- CommonActions.navigate({
- name: 'Profile',
- params: {
- user: 'jane',
- },
- })
-);
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
```
+
+
+
+```js name="Common actions navigate" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
In a stack navigator ([stack](stack-navigator.md) or [native stack](native-stack-navigator.md)), calling `navigate` with a screen name will have the following behavior:
- If you're already on a screen with the same name, it will update its params and not push a new screen.
- If you're on a different screen, it will push the new screen onto the stack.
-- If the [`getId`](screen.md#getid) prop is specified, and another screen in the stack has the same ID, it will navigate to that screen and update its params instead.
+- If the [`getId`](screen.md#id) prop is specified, and another screen in the stack has the same ID, it will bring that screen to focus and update its params instead.
+
+
+Advanced usage
The `navigate` action can also accepts an object as the argument with the following properties:
- `name` - _string_ - A destination name of the screen in the current or a parent navigator
- `params` - _object_ - Params to use for the destination route.
-- `merge` - _boolean_ - Whether we should merge the params of the current route with the provided `params`. Defaults to `false`.
+- `merge` - _boolean_ - Whether params should be merged with the existing route params, or replace them (when navigating to an existing screen). Defaults to `false`.
+- `pop` - _boolean_ - Whether screens should be popped to navigate to a matching screen in the stack. Defaults to `false`.
- `path` - _string_ - The path (from deep link or universal link) to associate with the screen.
+This is primarily used internally to associate a path with a screen when it's from a URL.
+
+
+
### reset
The `reset` action allows to reset the [navigation state](navigation-state.md) to the given state. It takes the following arguments:
- `state` - _object_ - The new [navigation state](navigation-state.md) object to use.
-
+
+
-```js
-import { CommonActions } from '@react-navigation/native';
+```js name="Common actions reset" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
-navigation.dispatch(
- CommonActions.reset({
- index: 1,
- routes: [
- { name: 'Home' },
- {
- name: 'Profile',
- params: { user: 'jane' },
- },
- ],
- })
-);
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ CommonActions.reset({
+ index: 1,
+ routes: [
+ {
+ name: 'Profile',
+ params: { user: 'jane', key: route.params.key },
+ },
+ { name: 'Home' },
+ ],
+ })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Reset navigation state
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
```
+
+
+
+```js name="Common actions reset" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ CommonActions.reset({
+ index: 1,
+ routes: [
+ {
+ name: 'Profile',
+ params: { user: 'jane', key: route.params.key },
+ },
+ { name: 'Home' },
+ ],
+ })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Reset navigation state
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
The state object specified in `reset` replaces the existing [navigation state](navigation-state.md) with the new one. This means that if you provide new route objects without a key, or route objects with a different key, it'll remove the existing screens for those routes and add new screens.
If you want to preserve the existing screens but only want to modify the state, you can pass a function to `dispatch` where you can get the existing state. Then you can change it as you like (make sure not to mutate the existing state, but create new state object for your changes). and return a `reset` action with the desired state:
@@ -86,9 +402,9 @@ If you want to preserve the existing screens but only want to modify the state,
```js
import { CommonActions } from '@react-navigation/native';
-navigation.dispatch(state => {
+navigation.dispatch((state) => {
// Remove all the screens after `Profile`
- const index = state.routes.findIndex(r => r.name === 'Profile');
+ const index = state.routes.findIndex((r) => r.name === 'Profile');
const routes = state.routes.slice(0, index + 1);
return CommonActions.reset({
@@ -118,55 +434,1280 @@ So if you have such a use case, consider a different approach - e.g. updating th
The `goBack` action creator allows to go back to the previous route in history. It doesn't take any arguments.
-
+
+
-```js
-import { CommonActions } from '@react-navigation/native';
+```js name="Common actions goBack" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(CommonActions.goBack());
+ // codeblock-focus-end
+ }}
+ >
+ Go back
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
-navigation.dispatch(CommonActions.goBack());
+
+
+
+```js name="Common actions goBack" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(CommonActions.goBack());
+ // codeblock-focus-end
+ }}
+ >
+ Go back
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
If you want to go back from a particular route, you can add a `source` property referring to the route key and a `target` property referring to the `key` of the navigator which contains the route:
-
+
+
-```js
-import { CommonActions } from '@react-navigation/native';
+```js name="Common actions goBack" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch({
+ ...CommonActions.goBack(),
+ source: route.key,
+ target: navigation.getState().key,
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Go back
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Common actions goBack" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ navigation.dispatch({
+ ...CommonActions.setParams({ user: 'Wojtek' }),
+ source: route.key,
+ });
+ }}
+ >
+ Change user param
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch({
+ ...CommonActions.goBack(),
+ source: route.key,
+ target: navigation.getState().key,
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Go back
+
+
+ );
+}
+
+const Stack = createStackNavigator();
-navigation.dispatch({
- ...CommonActions.goBack(),
- source: route.key,
- target: state.key,
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
+By default, the key of the route that dispatched the action is passed as the `source` property and the `target` property is `undefined`.
+
+### preload
+
+The `preload` action allows preloading a screen in the background before navigating to it. It takes the following arguments:
+
+- `name` - _string_ - A destination name of the screen in the current or a parent navigator.
+- `params` - _object_ - Params to use for the destination route.
+
+
+
+
+```js name="Common actions preload" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ CommonActions.preload('Profile', { user: 'jane' })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Preload Profile
+
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ const [startTime] = React.useState(Date.now());
+ const [endTime, setEndTime] = React.useState(null);
+
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('focus', () => {
+ setEndTime(Date.now());
+ });
+
+ return () => {
+ unsubscribe();
+ };
+ }, [navigation]);
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ Preloaded for: {endTime ? endTime - startTime : 'N/A'}ms
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Common actions preload" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ CommonActions.preload('Profile', { user: 'jane' })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Preload Profile
+
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ const [startTime] = React.useState(Date.now());
+ const [endTime, setEndTime] = React.useState(null);
+
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('focus', () => {
+ setEndTime(Date.now());
+ });
+
+ return () => {
+ unsubscribe();
+ };
+ }, [navigation]);
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ Preloaded for: {endTime ? endTime - startTime : 'N/A'}ms
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
-By default, the key of the route which dispatched the action is passed as the `source` property and the `target` property is `undefined`.
+
+
+
+Preloading a screen means that the screen will be rendered in the background. All the components in the screen will be mounted and the `useEffect` hooks will be called. This can be useful when you want to improve the perceived performance by hiding the delay in mounting heavy components or loading data.
+
+Depending on the navigator, `preload` may work differently:
+
+- In a stack navigator ([stack](stack-navigator.md), [native stack](native-stack-navigator.md)), the screen will be rendered off-screen and animated in when you navigate to it. If [`getId`](screen.md#id) is specified, it'll be used for the navigation to identify the preloaded screen.
+- In a tab or drawer navigator ([bottom tabs](bottom-tab-navigator.md), [material top tabs](material-top-tab-navigator.md), [drawer](drawer-navigator.md), etc.), the existing screen will be rendered as if `lazy` was set to `false`. Calling `preload` on a screen that is already rendered will not have any effect.
+
+When a screen is preloaded in a stack navigator, it will have a few limitations:
+
+- It can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.).
+- It can't update options with `navigation.setOptions`.
+- It can't listen to events from the navigator (e.g. `focus`, `tabPress`, etc.).
+
+The `navigation` object will be updated once you navigate to the screen. So if you have an event listener in a `useEffect` hook, and have a dependency on `navigation`, it will add any listeners when the screen is navigated to:
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('tabPress', () => {
+ // do something
+ });
+
+ return () => {
+ unsubscribe();
+ };
+}, [navigation]);
+```
+
+Similarly, for dispatching actions or updating options, you can check if the screen is focused before doing so:
+
+```js
+if (navigation.isFocused()) {
+ navigation.setOptions({ title: 'Updated title' });
+}
+```
### setParams
-The `setParams` action allows to update params for a certain route. It takes the following arguments:
+The `setParams` action allows to replace params for a certain route. It takes the following arguments:
- `params` - _object_ - required - New params to be merged into existing route params.
-
+
+
-```js
-import { CommonActions } from '@react-navigation/native';
+```js name="Common actions setParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(CommonActions.setParams({ user: 'Wojtek' }));
+ // codeblock-focus-end
+ }}
+ >
+ Set user param
+
+
+ );
+}
-navigation.dispatch(CommonActions.setParams({ user: 'Wojtek' }));
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
```
-If you want to set params for a particular route, you can add a `source` property referring to the route key:
+
+
-
+```js name="Common actions setParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
-```js
-import { CommonActions } from '@react-navigation/native';
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(CommonActions.setParams({ user: 'Wojtek' }));
+ // codeblock-focus-end
+ }}
+ >
+ Set user param
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
+If you want to replace params for a particular route, you can add a `source` property referring to the route key:
+
+
+
+
+```js name="Common actions setParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch({
+ ...CommonActions.setParams({ user: 'Wojtek' }),
+ source: route.key,
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Set user param
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Common actions setParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
-navigation.dispatch({
- ...CommonActions.setParams({ user: 'Wojtek' }),
- source: route.key,
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch({
+ ...CommonActions.setParams({ user: 'Wojtek' }),
+ source: route.key,
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Set user param
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
+If the `source` property is explicitly set to `undefined`, it'll replace the params for the focused route.
+
+### replaceParams
+
+The `replaceParams` action allows to replace params for a certain route. It takes the following arguments:
+
+- `params` - _object_ - required - New params to use for the route.
+
+
+
+
+```js name="Common actions replaceParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(CommonActions.replaceParams({ user: 'Wojtek' }));
+ // codeblock-focus-end
+ }}
+ >
+ Replace params with user
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Common actions replaceParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(CommonActions.replaceParams({ user: 'Wojtek' }));
+ // codeblock-focus-end
+ }}
+ >
+ Replace params with user
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
+If you want to replace params for a particular route, you can add a `source` property referring to the route key:
+
+
+
+
+```js name="Common actions replaceParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+ navigation.dispatch(CommonActions.goBack())}>
+ Go back
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch({
+ ...CommonActions.replaceParams({ user: 'Wojtek' }),
+ source: route.key,
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Replace params with user
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Common actions replaceParams" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ navigation.dispatch(
+ CommonActions.navigate('Profile', { user: 'jane' })
+ );
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch({
+ ...CommonActions.replaceParams({ user: 'Wojtek' }),
+ source: route.key,
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Replace params with user
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
-If the `source` property is explicitly set to `undefined`, it'll set the params for the focused route.
+
+
+
+If the `source` property is explicitly set to `undefined`, it'll replace the params for the focused route.
diff --git a/versioned_docs/version-7.x/navigation-container.md b/versioned_docs/version-7.x/navigation-container.md
index f4ddb71ac85..536dd908ae2 100644
--- a/versioned_docs/version-7.x/navigation-container.md
+++ b/versioned_docs/version-7.x/navigation-container.md
@@ -4,6 +4,9 @@ title: NavigationContainer
sidebar_label: NavigationContainer
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
The `NavigationContainer` is responsible for managing your app's navigation state and linking your top-level navigator to the app environment.
The container takes care of platform specific integration and provides various useful functionality:
@@ -14,6 +17,31 @@ The container takes care of platform specific integration and provides various u
Usage:
+
+
+
+When using the static API, the component returned by [`createStaticNavigation`](static-configuration.md#createstaticnavigation) is equivalent to the `NavigationContainer` component.
+
+```js
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator({
+ screens: {
+ /* ... */
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
```js
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
@@ -29,34 +57,117 @@ export default function App() {
}
```
+
+
+
## Ref
-It's also possible to attach a [`ref`](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) to the container to get access to various helper methods, for example, dispatch navigation actions. This should be used in rare cases when you don't have access to the [`navigation` object](navigation-object.md), such as a Redux middleware.
+It's possible to pass a [`ref`](https://react.dev/learn/referencing-values-with-refs) to the container to get access to various helper methods, for example, dispatch navigation actions. This should be used in rare cases when you don't have access to the [`navigation` object](navigation-object.md), such as a Redux middleware.
Example:
-
+
+
-```js
+```js name="Using refs" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
+import {
+ createStaticNavigation,
+ useNavigationContainerRef,
+} from '@react-navigation/native';
+// codeblock-focus-end
+import { createStackNavigator } from '@react-navigation/stack';
+
+const Stack = createStackNavigator({
+ initialRouteName: 'Empty',
+ screens: {
+ Empty: () => ,
+ Home: HomeScreen,
+ },
+});
+
+function HomeScreen() {
+ return (
+
+ Home Screen
+
+ );
+}
+
+const Navigation = createStaticNavigation(Stack);
+
+// codeblock-focus-start
+
+export default function App() {
+ // highlight-next-line
+ const navigationRef = useNavigationContainerRef(); // You can also use a regular ref with `React.useRef()`
+
+ return (
+
+ navigationRef.navigate('Home')}>Go home
+
+
+ );
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Using refs" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
import {
NavigationContainer,
useNavigationContainerRef,
} from '@react-navigation/native';
+// codeblock-focus-end
+import { createStackNavigator } from '@react-navigation/stack';
-function App() {
+const Stack = createStackNavigator();
+
+function HomeScreen() {
+ return (
+
+ Home Screen
+
+ );
+}
+
+// codeblock-focus-start
+
+export default function App() {
+ // highlight-next-line
const navigationRef = useNavigationContainerRef(); // You can also use a regular ref with `React.useRef()`
return (
navigationRef.navigate('Home')}>Go home
- {/* ... */}
+
+
+ } />
+
+
+
);
}
+// codeblock-focus-end
```
+
+
+
If you're using a regular ref object, keep in mind that the ref may be initially `null` in some situations (such as when linking is enabled). To make sure that the ref is initialized, you can use the [`onReady`](#onready) callback to get notified when the navigation container finishes mounting.
+Check how to setup `ref` with TypeScript [here](typescript.md#annotating-ref-on-navigationcontainer).
+
See the [Navigating without the navigation prop](navigating-without-navigation-prop.md) guide for more details.
### Methods on the ref
@@ -126,6 +237,19 @@ Note that the returned `options` object will be `undefined` if there are no navi
The `addListener` method lets you listen to the following events:
+##### `ready`
+
+The event is triggered when the navigation tree is ready. This is useful for cases where you want to wait until the navigation tree is mounted:
+
+```js
+const unsubscribe = navigationRef.addListener('ready', () => {
+ // Get the initial state of the navigation tree
+ console.log(navigationRef.getRootState());
+});
+```
+
+This is analogous to the [`onReady`](#onready) method.
+
##### `state`
The event is triggered whenever the [navigation state](navigation-state.md) changes in any navigator in the navigation tree:
@@ -161,12 +285,33 @@ Prop that accepts initial state for the navigator. This can be useful for cases
Example:
+
+
+
```js
-
+
+```
+
+
+
+
+```js
+
{/* ... */}
```
+
+
+
+See [Navigation state reference](navigation-state.md) for more details on the structure of the state object.
+
Providing a custom initial state object will override the initial state object obtained via linking configuration or from browser's URL. If you're providing an initial state object, make sure that you don't pass it on web and that there's no deep link to handle.
Example:
@@ -194,15 +339,31 @@ Function that gets called every time [navigation state](navigation-state.md) cha
You can use it to track the focused screen, persist the navigation state etc.
Example:
+
+
+
+```js
+ console.log('New state is', state)}
+/>
+```
+
+
+
```js
console.log('New state is', state)}
>
{/* ... */}
```
+
+
+
### `onReady`
Function which is called after the navigation container and all its children finish mounting for the first time. You can use it for:
@@ -212,14 +373,31 @@ Function which is called after the navigation container and all its children fin
Example:
+
+
+
+```js
+ console.log('Navigation container is ready')}
+/>
+```
+
+
+
+
```js
console.log('Navigation container is ready')}
>
{/* ... */}
```
+
+
+
This callback won't fire if there are no navigators rendered inside the container.
The current status can be obtained with the [`isReady`](#isready) method on the ref.
@@ -228,7 +406,34 @@ The current status can be obtained with the [`isReady`](#isready) method on the
Function which is called when a navigation action is not handled by any of the navigators.
-By default, React Navigation will show a development-only error message when an action was not handled. You can override the default behavior by providing a custom function.
+By default, React Navigation will show a development-only error message when an action is not handled. You can override the default behavior by providing a custom function.
+
+Example:
+
+
+
+
+```js
+ console.error('Unhandled action', action)}
+/>
+```
+
+
+
+
+```js
+ console.error('Unhandled action', action)}
+>
+ {/* ... */}
+
+```
+
+
+
### `linking`
@@ -236,12 +441,50 @@ Configuration for linking integration used for deep linking, URL support in brow
Example:
+
+
+
+```js
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: Home,
+ linking: {
+ path: 'feed/:sort',
+ },
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+function App() {
+ const linking = {
+ prefixes: ['https://example.com', 'example://'],
+ };
+
+ return (
+ Loading...}
+ />
+ );
+}
+```
+
+
+
+
```js
import { NavigationContainer } from '@react-navigation/native';
function App() {
const linking = {
- prefixes: ['https://mychat.com', 'mychat://'],
+ prefixes: ['https://example.com', 'example://'],
config: {
screens: {
Home: 'feed/:sort',
@@ -250,13 +493,19 @@ function App() {
};
return (
- Loading...}>
+ Loading...}
+ >
{/* content */}
);
}
```
+
+
See [configuring links guide](configuring-links.md) for more details on how to configure deep links and URL integration.
#### Options
@@ -269,14 +518,29 @@ Only URLs matching these prefixes will be handled. The prefix will be stripped f
Example:
+
+
+
+```js
+Loading...}
+/>
+```
+
+
+
+
```js
@@ -284,130 +548,76 @@ Example:
```
+
+
+
This is only supported on iOS and Android.
##### `linking.config`
-Config to fine-tune how to parse the path. The config object should represent the structure of the navigators in the app.
+Config to fine-tune how to parse the path.
-For example, if we have `Catalog` screen inside `Home` screen and want it to handle the `item/:id` pattern:
+When using dynamic API, the config object should represent the structure of the navigators in the app.
-```js
-{
- screens: {
- Home: {
- screens: {
- Catalog: {
- path: 'item/:id',
- parse: {
- id: Number,
- },
- },
- },
- },
- }
-}
-```
+See the [configuring links guide](configuring-links.md) for more details on how to configure deep links and URL integration.
-The options for parsing can be an object or a string:
+##### `linking.enabled`
-```js
-{
- screens: {
- Catalog: 'item/:id',
- }
-}
-```
+Optional boolean to enable or disable the linking integration. Defaults to `true` if the `linking` prop is specified.
-When a string is specified, it's equivalent to providing the `path` option.
+When using the static API, it's possible to pass `'auto'` to automatically generate the config based on the navigator's structure. See the [configuring links guide](configuring-links.md) for more details.
-The `path` option is a pattern to match against the path. Any segments starting with `:` are recognized as a param with the same name. For example `item/42` will be parsed to `{ name: 'item', params: { id: '42' } }`.
+##### `linking.getInitialURL`
-The `initialRouteName` option ensures that the route name passed there will be present in the state for the navigator, e.g. for config:
+By default, linking integrates with React Native's `Linking` API and uses `Linking.getInitialURL()` to provide built-in support for deep linking. However, you might also want to handle links from other sources, such as [Branch](https://help.branch.io/developers-hub/docs/react-native), or push notifications using [Firebase](https://rnfirebase.io/messaging/notifications) etc.
-```js
-{
- screens: {
- Home: {
- initialRouteName: 'Feed',
- screens: {
- Catalog: {
- path: 'item/:id',
- parse: {
- id: Number,
- },
- },
- Feed: 'feed',
- },
- },
- }
-}
-```
+You can provide a custom `getInitialURL` function where you can return the link which we should use as the initial URL. The `getInitialURL` function should return a `string` if there's a URL to handle, otherwise `undefined`.
-and URL : `/item/42`, the state will look like this:
-
-```js
-{
- routes: [
- {
- name: 'Home',
- state: {
- index: 1,
- routes: [
- {
- name: 'Feed'
- },
- {
- name: 'Catalog',
- params: { id: 42 },
- },
- ],
- },
- },
- ],
-}
-```
+For example, you could do something like following to handle both deep linking and [Firebase notifications](https://rnfirebase.io/messaging/notifications):
-The `parse` option controls how the params are parsed. Here, you can provide the name of the param to parse as a key, and a function which takes the string value for the param and returns a parsed value:
+
+
```js
-{
- screens: {
- Catalog: {
- path: 'item/:id',
- parse: {
- id: id => parseInt(id, 10),
- },
- },
- }
-}
-```
-
-If no custom function is provided for parsing a param, it'll be parsed as a string.
-
-##### `linking.enabled`
+import messaging from '@react-native-firebase/messaging';
-Optional boolean to enable or disable the linking integration. Defaults to `true` if the `linking` prop is specified.
+ ;
+```
-For example, you could do something like following to handle both deep linking and [Firebase notifications](https://rnfirebase.io/messaging/notifications):
+
+
```js
import messaging from '@react-native-firebase/messaging';
{/* content */}
;
```
+
+
+
This option is not available on Web.
##### `linking.subscribe`
@@ -437,17 +651,61 @@ Similar to [`getInitialURL`](#linkinggetinitialurl), you can provide a custom `s
For example, you could do something like following to handle both deep linking and [Firebase notifications](https://rnfirebase.io/messaging/notifications):
+
+
+
+```js
+import messaging from '@react-native-firebase/messaging';
+
+ listener(url);
+
+ // Listen to incoming links from deep linking
+ const subscription = Linking.addEventListener('url', onReceiveURL);
+
+ // Listen to firebase push notifications
+ const unsubscribeNotification = messaging().onNotificationOpenedApp(
+ (message) => {
+ const url = message.data?.url;
+
+ if (url) {
+ // Any custom logic to check whether the URL needs to be handled
+ //...
+
+ // Call the listener to let React Navigation handle the URL
+ listener(url);
+ }
+ }
+ );
+
+ return () => {
+ // Clean up the event listeners
+ subscription.remove();
+ unsubscribeNotification();
+ };
+ },
+ // highlight-end
+ }}
+/>
+```
+
+
+
+
```js
import messaging from '@react-native-firebase/messaging';
listener(url);
@@ -475,68 +733,195 @@ import messaging from '@react-native-firebase/messaging';
unsubscribeNotification();
};
},
+ // highlight-end
}}
>
{/* content */}
;
```
+
+
+
This option is not available on Web.
##### `linking.getStateFromPath`
-You can optionally override the way React Navigation parses links to a state object by providing your own implementation.
+React Navigation handles deep links and [URLs on Web](web-support.md) by parsing the path to a [navigation state](navigation-state.md) object based on the [linking config](#linkingconfig). You can optionally override the way the parsing happens by providing your own `getStateFromPath` function.
Example:
+
+
+
+```js
+
+```
+
+
+
+
```js
{/* content */}
```
+
+
+
##### `linking.getPathFromState`
-You can optionally override the way React Navigation serializes state objects to link by providing your own implementation. This is necessary for proper web support if you have specified `getStateFromPath`.
+On Web, React Navigation automatically updates the [URL in the browser's address bar](web-support.md) to match the current navigation state by serializing the state to a path based on the [linking config](#linkingconfig). You can optionally override the way the serialization happens by providing your own `getPathFromState` function.
+
+If you provide a custom [`getStateFromPath`](#linkinggetstatefrompath), you should also provide a custom `getPathFromState` to ensure that the parsing and serialization are consistent with each other for Web support to work correctly.
Example:
+
+
+
+```js
+
+```
+
+
+
+
```js
{/* content */}
```
+
+
+
+##### `linking.getActionFromState`
+
+The state parsed with [`getStateFromPath`](#linkinggetstatefrompath) is used as the initial state of the navigator. But for subsequent deep links and URLs, the state is converted to a navigation action. Typically it is a [`navigate`](navigation-actions.md#navigate) action.
+
+You can provide a custom `getActionFromState` function to customize how the state is converted to an action.
+
+Example:
+
+
+
+
+```js
+
+```
+
+
+
+
+```js
+
+ {/* content */}
+
+```
+
+
+
+
### `fallback`
React Element to use as a fallback while we resolve deep links. Defaults to `null`.
+
+
+
+```js
+Loading...}
+/>
+```
+
+
+
+
+```js
+Loading...}
+>
+ {/* content */}
+
+```
+
+
+
+
If you have a native splash screen, please use [`onReady`](#onready) instead of `fallback` prop.
### `documentTitle`
@@ -557,27 +942,103 @@ Custom formatter to use if you want to customize the title text. Defaults to:
Example:
+
+
+
```js
-import { NavigationContainer } from '@react-navigation/native';
+
+ `${options?.title ?? route?.name} - My Cool App`,
+ }}
+ // highlight-end
+/>
+```
-function App() {
- return (
-
- `${options?.title ?? route?.name} - My Cool App`,
- }}
- >
- {/* content */}
-
- );
-}
+
+
+
+```js
+
+ `${options?.title ?? route?.name} - My Cool App`,
+ }}
+ // highlight-end
+>
+ {/* content */}
+
```
+
+
+
### `theme`
Custom theme to use for the navigation components such as the header, tab bar etc. See [theming guide](themes.md) for more details and usage guide.
+### `direction`
+
+The direction of the text configured in the app. Defaults to `'rtl'` when `I18nManager.getConstants().isRTL` returns `true`, otherwise `'ltr'`.
+
+Supported values:
+
+- `'ltr'`: Left-to-right text direction for languages like English, French etc.
+- `'rtl'`: Right-to-left text direction for languages like Arabic, Hebrew etc.
+
+Example:
+
+
+
+
+```js
+
+```
+
+
+
+
+```js
+
+ {/* content */}
+
+```
+
+
+
+
+This is used in various navigators to adjust the content according to the text direction, for example, the drawer in the [drawer navigator](drawer-navigator.md) is positioned on the right side in RTL languages.
+
+This prop informs React Navigation about the text direction in the app, it doesn't change the text direction by itself. If you intend to support RTL languages, it's important to set this prop to the correct value that's configured in the app. If it doesn't match the actual text direction, the layout might be incorrect.
+
+On the Web, it may also be necessary to set the `dir` attribute on the root element of the app to ensure that the text direction is correct:
+
+```html
+
+
+
+```
+
+The `direction` will be available to use in your own components via the `useLocale` hook:
+
+```js
+import { useLocale } from '@react-navigation/native';
+
+function MyComponent() {
+ const { direction } = useLocale();
+
+ // Use the direction
+}
+```
+
### `navigationInChildEnabled`
:::warning
@@ -609,6 +1070,33 @@ In most apps, there will be only a single `NavigationContainer`. Nesting multipl
You can wrap the nested `NavigationContainer` with the `NavigationIndependentTree` component to make it independent from the parent navigation tree:
+
+
+
+```js
+import {
+ createStaticNavigation,
+ NavigationIndependentTree,
+} from '@react-navigation/native';
+
+/* content */
+
+const Navigation = createStaticNavigation(RootStack);
+
+function NestedApp() {
+ return (
+ // highlight-start
+
+
+
+ // highlight-end
+ );
+}
+```
+
+
+
+
```js
import {
NavigationContainer,
@@ -617,13 +1105,18 @@ import {
function NestedApp() {
return (
+ // highlight-start
{/* content */}
+ // highlight-end
);
}
```
+
+
+
Doing this disconnects any children navigators from the parent container and doesn't allow navigation between them.
Avoid using this if you need to integrate with third-party components such as modals or bottom sheets. Consider using a [custom navigator](custom-navigators.md) instead.
diff --git a/versioned_docs/version-7.x/navigation-context.md b/versioned_docs/version-7.x/navigation-context.md
index 7b31dd0b654..90db5663241 100755
--- a/versioned_docs/version-7.x/navigation-context.md
+++ b/versioned_docs/version-7.x/navigation-context.md
@@ -4,19 +4,138 @@ title: NavigationContext
sidebar_label: NavigationContext
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`NavigationContext` provides the `navigation` object (same object as the [navigation](navigation-object.md) prop). In fact, [useNavigation](use-navigation.md) uses this context to get the `navigation` prop.
Most of the time, you won't use `NavigationContext` directly, as the provided `useNavigation` covers most use cases. But just in case you have something else in mind, `NavigationContext` is available for you to use.
Example:
-
+
+
-```js
+```js name="Navigation context" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
import { NavigationContext } from '@react-navigation/native';
+// codeblock-focus-end
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ return ;
+}
+
+// codeblock-focus-start
function SomeComponent() {
// We can access navigation object via context
const navigation = React.useContext(NavigationContext);
+ // codeblock-focus-end
+
+ return (
+
+ Some component inside HomeScreen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
}
+
+export default App;
```
+
+
+
+
+```js name="Navigation context" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
+import { NavigationContext } from '@react-navigation/native';
+// codeblock-focus-end
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ return ;
+}
+
+// codeblock-focus-start
+
+function SomeComponent() {
+ // We can access navigation object via context
+ const navigation = React.useContext(NavigationContext);
+ // codeblock-focus-end
+
+ return (
+
+ Some component inside HomeScreen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = React.useContext(NavigationContext);
+
+ return (
+
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default App;
+```
+
+
+
diff --git a/versioned_docs/version-7.x/navigation-events.md b/versioned_docs/version-7.x/navigation-events.md
index f442487b8e5..1d3c6430a14 100644
--- a/versioned_docs/version-7.x/navigation-events.md
+++ b/versioned_docs/version-7.x/navigation-events.md
@@ -4,6 +4,9 @@ title: Navigation events
sidebar_label: Navigation events
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
You can listen to various events emitted by React Navigation to get notified of certain events, and in some cases, override the default action. There are few core events such as `focus`, `blur` etc. (documented below) that work for every navigator, as well as navigator specific events that work only for certain navigators.
Apart from the core events, each navigator can emit their own custom events. For example, stack navigator emits `transitionStart` and `transitionEnd` events, tab navigator emits `tabPress` event etc. You can find details about the events emitted on the individual navigator's documentation.
@@ -22,13 +25,62 @@ For most cases, the [`useFocusEffect`](use-focus-effect.md) hook might be approp
This event is emitted when the screen goes out of focus.
+:::note
+
+In some cases, such as going back from a screen in [native-stack navigator](native-stack-navigator.md), the screen may not receive the `blur` event as the screen is unmounted immediately. For cleaning up resources, it's recommended to use the cleanup function of [`useFocusEffect`](use-focus-effect.md) hook instead that considers both blur and unmounting of the screen.
+
+:::
+
### `state`
This event is emitted when the navigator's state changes. This event receives the navigator's state in the event data (`event.data.state`).
### `beforeRemove`
-This event is emitted when the user is leaving the screen, there's a chance to [prevent the user from leaving](preventing-going-back.md).
+This event is emitted when the user is leaving the screen due to a navigation action. It is possible to prevent the user from leaving the screen by calling `e.preventDefault()` in the event listener.
+
+```js
+React.useEffect(
+ () =>
+ navigation.addListener('beforeRemove', (e) => {
+ if (!hasUnsavedChanges) {
+ return;
+ }
+
+ // Prevent default behavior of leaving the screen
+ e.preventDefault();
+
+ // Prompt the user before leaving the screen
+ Alert.alert(
+ 'Discard changes?',
+ 'You have unsaved changes. Are you sure to discard them and leave the screen?',
+ [
+ {
+ text: "Don't leave",
+ style: 'cancel',
+ onPress: () => {
+ // Do nothing
+ },
+ },
+ {
+ text: 'Discard',
+ style: 'destructive',
+ // If the user confirmed, then we dispatch the action we blocked earlier
+ // This will continue the action that had triggered the removal of the screen
+ onPress: () => navigation.dispatch(e.data.action),
+ },
+ ]
+ );
+ }),
+ [navigation, hasUnsavedChanges]
+);
+```
+
+:::warning
+
+Preventing the action in this event doesn't work properly with [`@react-navigation/native-stack`](native-stack-navigator.md). We recommend using the [`usePreventRemove` hook](preventing-going-back.md) instead.
+
+:::
## Listening to events
@@ -55,22 +107,146 @@ const unsubscribe = navigation.addListener('tabPress', (e) => {
Normally, you'd add an event listener in `React.useEffect` for function components. For example:
-
+
+
+
+```js name="navigation.addListener with focus" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function SettingsScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Settings Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen() {
+ const navigation = useNavigation();
-```js
-function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
- // do something
+ // Screen was focused
});
+ return unsubscribe;
+ }, [navigation]);
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('blur', () => {
+ // Screen was unfocused
+ });
return unsubscribe;
}, [navigation]);
- return ;
+ // Rest of the component
+ // codeblock-focus-end
+ return (
+
+ Profile Screen
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+ // codeblock-focus-start
+}
+// codeblock-focus-end
+
+const SettingsStack = createNativeStackNavigator({
+ screens: {
+ Settings: SettingsScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(SettingsStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="navigation.addListener with focus" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function SettingsScreen({ navigation }) {
+ return (
+
+ Settings Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ navigation }) {
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('focus', () => {
+ // Screen was focused
+ });
+ return unsubscribe;
+ }, [navigation]);
+
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('blur', () => {
+ // Screen was unfocused
+ });
+ return unsubscribe;
+ }, [navigation]);
+
+ // Rest of the component
+ // codeblock-focus-end
+ return (
+
+ Profile Screen
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+ // codeblock-focus-start
+}
+// codeblock-focus-end
+
+const SettingsStack = createNativeStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
The `unsubscribe` function can be returned as the cleanup function in the effect.
For class components, you can add the event in the `componentDidMount` lifecycle method and unsubscribe in `componentWillUnmount`:
@@ -93,7 +269,7 @@ class Profile extends React.Component {
}
```
-One thing to keep in mind is that you can only listen to events from the immediate navigator with `addListener`. For example, if you try to add a listener in a screen that's inside a stack that's nested in a tab, it won't get the `tabPress` event. If you need to listen to an event from a parent navigator, you may use [`navigation.getParent`](navigation-object.md#getparent) to get a reference to the parent screen's navigation object and add a listener.
+Keep in mind that you can only listen to events from the immediate navigator with `addListener`. For example, if you try to add a listener in a screen that's inside a stack that's nested in a tab, it won't get the `tabPress` event. If you need to listen to an event from a parent navigator, you may use [`navigation.getParent`](navigation-object.md#getparent) to get a reference to the parent screen's navigation object and add a listener.
```js
const unsubscribe = navigation
@@ -105,12 +281,40 @@ const unsubscribe = navigation
Here `'MyTabs'` refers to the value you pass in the `id` prop of the parent `Tab.Navigator` whose event you want to listen to.
+:::warning
+
+The component needs to be rendered for the listeners to be added in `useEffect` or `componentDidMount`. Navigators such as [bottom tabs](bottom-tab-navigator.md) and [drawer](drawer-navigator.md) lazily render the screen after navigating to it. So if your listener is not being called, double check that the component is rendered.
+
+:::
+
### `listeners` prop on `Screen`
Sometimes you might want to add a listener from the component where you defined the navigator rather than inside the screen. You can use the `listeners` prop on the `Screen` component to add listeners. The `listeners` prop takes an object with the event names as keys and the listener callbacks as values.
Example:
+
+
+
+```js
+const Tab = createBottomTabNavigatior({
+ screens: {
+ Chat: {
+ screen: Chat,
+ listeners: {
+ tabPress: (e) => {
+ // Prevent default action
+ e.preventDefault;
+ },
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
```
+
+
+
You can also pass a callback which returns the object with listeners. It'll receive `navigation` and `route` as the arguments.
Example:
+
+
+
+```js
+const Tab = createBottomTabNavigatior({
+ screens: {
+ Chat: {
+ screen: Chat,
+ listeners: ({ navigation, route }) => ({
+ tabPress: (e) => {
+ // Prevent default action
+ e.preventDefault;
+
+ // Do something with the `navigation` object
+ navigation.navigate('AnotherPlace');
+ },
+ }),
+ },
+ },
+});
+```
+
+
+
```js
```
+
+
+
### `screenListeners` prop on the navigator
You can pass a prop named `screenListeners` to the navigator component, where you can specify listeners for events from all screens for this navigator. This can be useful if you want to listen to specific events regardless of the screen, or want to listen to common events such as `state` which is emitted to all screens.
Example:
+
+
+
+```js
+const Stack = createNativeStackNavigator({
+ screenListeners: {
+ state: (e) => {
+ // Do something with the state
+ console.log('state changed', e.data);
+ },
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
```js
```
+
+
+
Similar to `listeners`, you can also pass a function to `screenListeners`. The function will receive the [`navigation` object](navigation-object.md) and the [`route` object](route-object.md) for each screen. This can be useful if you need access to the `navigation` object.
+
+
+
+```js
+const Tab = createBottomTabNavigatior({
+ screenListeners: ({ navigation }) => ({
+ state: (e) => {
+ // Do something with the state
+ console.log('state changed', e.data);
+
+ // Do something with the `navigation` object
+ if (!navigation.canGoBack()) {
+ console.log("we're on the initial screen");
+ }
+ },
+ }),
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
```js
({
@@ -184,3 +468,6 @@ Similar to `listeners`, you can also pass a function to `screenListeners`. The f
```
+
+
+
diff --git a/versioned_docs/version-7.x/navigation-lifecycle.md b/versioned_docs/version-7.x/navigation-lifecycle.md
index f854eb1ff1e..d2a2317652b 100755
--- a/versioned_docs/version-7.x/navigation-lifecycle.md
+++ b/versioned_docs/version-7.x/navigation-lifecycle.md
@@ -24,15 +24,16 @@ Similar results can be observed (in combination) with other navigators as well.
-```js name="Navigation lifecycle" snack version=7
+```js name="Navigation lifecycle" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function SettingsScreen() {
const navigation = useNavigation();
@@ -46,10 +47,9 @@ function SettingsScreen() {
return (
Settings Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -66,10 +66,9 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Settings')}
- />
+ navigation.navigate('Settings')}>
+ Go to Settings
+
);
}
@@ -86,10 +85,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -106,10 +104,9 @@ function DetailsScreen() {
return (
Details Screen
- navigation.push('Details')}
- />
+ navigation.push('Details')}>
+ Go to Details... again
+
);
}
@@ -150,12 +147,13 @@ export default function App() {
-```js name="Navigation lifecycle" snack version=7
+```js name="Navigation lifecycle" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function SettingsScreen() {
const navigation = useNavigation();
@@ -169,10 +167,9 @@ function SettingsScreen() {
return (
Settings Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -189,10 +186,9 @@ function ProfileScreen() {
return (
Profile Screen
- navigation.navigate('Settings')}
- />
+ navigation.navigate('Settings')}>
+ Go to Settings
+
);
}
@@ -209,10 +205,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
);
}
@@ -229,10 +224,9 @@ function DetailsScreen() {
return (
Details Screen
- navigation.push('Details')}
- />
+ navigation.push('Details')}>
+ Go to Details... again
+
);
}
@@ -282,6 +276,10 @@ export default function App() {
+
+
+
+
We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the tab bar to switch to the `SettingsScreen` and navigate to `ProfileScreen`. After this sequence of operations is done, all 4 of the screens are mounted! If you use the tab bar to switch back to the `HomeStack`, you'll notice you'll be presented with the `DetailsScreen` - the navigation state of the `HomeStack` has been preserved!
## React Navigation lifecycle events
@@ -295,14 +293,15 @@ Example:
-```js name="Focus and blur" snack version=7
+```js name="Focus and blur" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
function ProfileScreen() {
@@ -358,10 +357,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -383,11 +381,12 @@ export default function App() {
-```js name="Focus and blur" snack version=7
+```js name="Focus and blur" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
function ProfileScreen() {
@@ -443,10 +442,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -476,21 +474,22 @@ export default function App() {
See [Navigation events](navigation-events.md) for more details on the available events and the API usage.
-Instead of adding event listeners manually, we can use the [`useFocusEffect`](use-focus-effect.md) hook to perform side effects. It's like React's `useEffect` hook, but it ties into the navigation lifecycle.
+For performing side effects, we can use the [`useFocusEffect`](use-focus-effect.md) hook instead of subscribing to events. It's like React's `useEffect` hook, but it ties into the navigation lifecycle.
Example:
-```js name="Focus effect" snack version=7
+```js name="Focus effect" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { useFocusEffect } from '@react-navigation/native';
@@ -524,10 +523,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -549,11 +547,12 @@ export default function App() {
-```js name="Focus effect" snack version=7
+```js name="Focus effect" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { useFocusEffect } from '@react-navigation/native';
@@ -587,10 +586,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -618,9 +616,17 @@ export default function App() {
+
+
+
+
If you want to render different things based on if the screen is focused or not, you can use the [`useIsFocused`](use-is-focused.md) hook which returns a boolean indicating whether the screen is focused.
+If you want to know if the screen is focused or not inside of an event listener, you can use the [`navigation.isFocused()`](navigation-object.md#isfocused) method. Note that using this method doesn't trigger a re-render like the `useIsFocused` hook does, so it is not suitable for rendering different things based on focus state.
+
## Summary
-- While React's lifecycle methods are still valid, React Navigation adds more events that you can subscribe to through the `navigation` object.
-- You may also use the `useFocusEffect` or `useIsFocused` hooks.
+- React Navigation does not unmount screens when navigating away from them
+- The [`useFocusEffect`](use-focus-effect.md) hook is analogous to React's [`useEffect`](https://react.dev/reference/react/useEffect) but is tied to the navigation lifecycle instead of the component lifecycle.
+- The [`useIsFocused`](use-is-focused.md) hook and [`navigation.isFocused()`](navigation-object.md#isfocused) method can be used to determine if a screen is currently focused.
+- React Navigation emits [`focus`](navigation-events.md#focus) and [`blur`](navigation-events.md#blur) events that can be listened to when a screen comes into focus or goes out of focus.
diff --git a/versioned_docs/version-7.x/navigation-object.md b/versioned_docs/version-7.x/navigation-object.md
index 5b345e5d8e4..42af46e61b2 100755
--- a/versioned_docs/version-7.x/navigation-object.md
+++ b/versioned_docs/version-7.x/navigation-object.md
@@ -4,17 +4,25 @@ title: Navigation object reference
sidebar_label: Navigation object
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
The `navigation` object contains various convenience functions that dispatch navigation actions. It looks like this:
- `navigation`
- - `navigate` - go to another screen, figures out the action it needs to take to do it
- - `reset` - wipe the navigator state and replace it with a new route
- - `goBack` - close active screen and move back in the stack
- - `setParams` - make changes to route's params
+ - `navigate` - go to the given screen, this will behave differently based on the navigator
+ - `goBack` - go back to the previous screen, this will pop the current screen when used in a stack
+ - `reset` - replace the navigation state of the navigator with the given state
+ - `preload` - preload a screen in the background before navigating to it
+ - `setParams` - merge new params onto the route's params
- `dispatch` - send an action object to update the [navigation state](navigation-state.md)
- `setOptions` - update the screen's options
- `isFocused` - check whether the screen is focused
- - `addListener` - subscribe to updates to events from the navigators
+ - `canGoBack` - check whether it's possible to go back from the current screen
+ - `getState` - get the navigation state of the navigator
+ - `getParent` - get the navigation object of the parent screen, if any
+ - `addListener` - subscribe to events for the screen
+ - `removeListener` - unsubscribe from events for the screen
The `navigation` object can be accessed inside any screen component with the [`useNavigation`](use-navigation.md) hook. It's also passed as a prop only to screens components defined with the dynamic API.
@@ -66,42 +74,208 @@ The `navigate` method lets us navigate to another screen in your app. It takes t
`navigation.navigate(name, params)`
-- `name` - A destination name of the route that has been defined somewhere
-- `params` - Params to pass to the destination route.
+- `name` - _string_ - A destination name of the screen in the current or a parent navigator.
+- `params` - _object_ - Params to use for the destination route.
+- `options` - Options object containing the following properties:
+ - `merge` - _boolean_ - Whether params should be merged with the existing route params, or replace them (when navigating to an existing screen). Defaults to `false`.
+ - `pop` - _boolean_ - Whether screens should be popped to navigate to a matching screen in the stack. Defaults to `false`.
+
+
+
+
+```js name="Navigate method" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ // highlight-start
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ // highlight-end
+ }}
+ >
+ Go to Brent's profile
+
+
+ );
+}
+// codeblock-focus-end
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
-
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.names[0]}
+ {route.params.names[1]}
+ {route.params.names[2]}
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
+```
+
+
+
+
+```js name="Navigate method" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
-```js
-function HomeScreen({ navigation: { navigate } }) {
return (
-
+
This is the home screen of the app
- navigate('Profile', { names: ['Brent', 'Satya', 'Michaś'] })
- }
- title="Go to Brent's profile"
- />
+ onPress={() => {
+ // highlight-start
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ // highlight-end
+ }}
+ >
+ Go to Brent's profile
+
);
}
+// codeblock-focus-end
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.names[0]}
+ {route.params.names[1]}
+ {route.params.names[2]}
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default App;
```
+
+
+
In a stack navigator ([stack](stack-navigator.md) or [native stack](native-stack-navigator.md)), calling `navigate` with a screen name will have the following behavior:
- If you're already on a screen with the same name, it will update its params and not push a new screen.
- If you're on a different screen, it will push the new screen onto the stack.
-- If the [`getId`](screen.md#getid) prop is specified, and another screen in the stack has the same ID, it will navigate to that screen and update its params instead.
+- If the [`getId`](screen.md#id) prop is specified, and another screen in the stack has the same ID, it will bring that screen to focus and update its params instead.
+- If none of the above conditions match, it'll push a new screen to the stack.
-By default, the screen is identified by its name. But you can also customize it to take the params into account by using the [`getId`](screen.md#getid) prop.
+In a tab or drawer navigator, calling `navigate` will switch to the relevant screen if it's not focused already and update the params of the screen.
-For example, say you have specified a `getId` prop for `Profile` screen:
+### `navigateDeprecated`
-```js
- params.userId} />
-```
+:::warning
+
+This method is deprecated and will be removed in a future release. It only exists for compatibility purposes. Use `navigate` instead.
+
+:::
+
+The `navigateDeprecated` action implements the old behavior of `navigate` from previous versions.
+
+It takes the following arguments:
+
+`navigation.navigateDeprecated(name, params)`
+
+- `name` - _string_ - A destination name of the screen in the current or a parent navigator.
+- `params` - _object_ - Params to use for the destination route.
+
+In a stack navigator ([stack](stack-navigator.md) or [native stack](native-stack-navigator.md)), calling `navigate` with a screen name will have the following behavior:
+
+- If you're already on a screen with the same name, it will update its params and not push a new screen.
+- If you're on a different screen, it will push the new screen onto the stack.
+- If the [`getId`](screen.md#id) prop is specified, and another screen in the stack has the same ID, it will bring that screen to focus and update its params instead.
-Now, if you have a stack with the history `Home > Profile (userId: bob) > Settings` and you call `navigate(Profile, { userId: 'alice' })`, the resulting screens will be `Home > Profile (userId: bob) > Settings > Profile (userId: alice)` since it'll add a new `Profile` screen as no matching screen was found.
+In a tab or drawer navigator, calling `navigate` will switch to the relevant screen if it's not focused already and update the params of the screen.
### `goBack`
@@ -109,31 +283,449 @@ The `goBack` method lets us go back to the previous screen in the navigator.
By default, `goBack` will go back from the screen that it is called from:
-
+
+
+
+```js name="Navigate method" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ }}
+ >
+ Go to Brent's profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.names[0]}
+ {route.params.names[1]}
+ {route.params.names[2]}
+ // highlight-next-line
+ navigation.goBack()}>Go back
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
+```
+
+
+
+
+```js name="Navigate method" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ }}
+ >
+ Go to Brent's profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
-```js
-function ProfileScreen({ navigation: { goBack } }) {
return (
-
- goBack()} title="Go back from ProfileScreen" />
+
+ Profile Screen
+ Friends:
+ {route.params.names[0]}
+ {route.params.names[1]}
+ {route.params.names[2]}
+ // highlight-next-line
+ navigation.goBack()}>Go back
);
}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default App;
```
+
+
+
### `reset`
The `reset` method lets us replace the navigator state with a new state:
-
+
+
-```js
-navigation.reset({
- index: 0,
- routes: [{ name: 'Profile' }],
+```js name="Navigation object replace and reset" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.names[0]}
+ {route.params.names[1]}
+ {route.params.names[2]}
+ navigation.goBack()}>Go back
+ {
+ navigation.replace('Settings', {
+ someParam: 'Param',
+ });
+ }}
+ >
+ Replace this screen with Settings
+
+ {
+ // codeblock-focus-start
+ navigation.reset({
+ index: 0,
+ routes: [
+ {
+ name: 'Settings',
+ params: { someParam: 'Param1' },
+ },
+ ],
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Reset navigator state to Settings
+
+ navigation.navigate('Home')}> Go to Home
+ navigation.navigate('Settings', { someParam: 'Param1' })}
+ >
+ Go to Settings
+
+
+ );
+}
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Settings screen
+ {route.params.someParam}
+ navigation.goBack()}>Go back
+ {
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
```
+
+
+
+```js name="Navigation object replace and reset" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.names[0]}
+ {route.params.names[1]}
+ {route.params.names[2]}
+ navigation.goBack()}>Go back
+
+ navigation.replace('Settings', {
+ someParam: 'Param',
+ })
+ }
+ >
+ Replace this screen with Settings
+
+ {
+ // codeblock-focus-start
+ navigation.reset({
+ index: 0,
+ routes: [
+ {
+ name: 'Settings',
+ params: { someParam: 'Param1' },
+ },
+ ],
+ });
+ // codeblock-focus-end
+ }}
+ >
+ Reset navigator state to Settings
+
+ navigation.navigate('Home')}> Go to Home
+ navigation.navigate('Settings', { someParam: 'Param1' })}
+ >
+ {' '}
+ Go to Settings{' '}
+
+
+ );
+}
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Settings screen
+ {route.params.someParam}
+ navigation.goBack()}>Go back
+ {
+ navigation.navigate('Profile', {
+ names: ['Brent', 'Satya', 'Michaś'],
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+export default App;
+```
+
+
+
+
The state object specified in `reset` replaces the existing [navigation state](navigation-state.md) with the new one, i.e. removes existing screens and add new ones. If you want to preserve the existing screens when changing the state, you can use [`CommonActions.reset`](navigation-actions.md#reset) with [`dispatch`](#dispatch) instead.
:::warning
@@ -142,63 +734,833 @@ Consider the navigator's state object to be internal and subject to change in a
:::
+### `preload`
+
+The `preload` method allows preloading a screen in the background before navigating to it. It takes the following arguments:
+
+- `name` - _string_ - A destination name of the screen in the current or a parent navigator.
+- `params` - _object_ - Params to use for the destination route.
+
+
+
+
+```js name="Common actions preload" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+ CommonActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ // highlight-next-line
+ navigation.preload('Profile', { user: 'jane' });
+ }}
+ >
+ Preload Profile
+
+ {
+ navigation.navigate('Profile', { user: 'jane' });
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+// codeblock-focus-end
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ const [startTime] = React.useState(Date.now());
+ const [endTime, setEndTime] = React.useState(null);
+
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('focus', () => {
+ setEndTime(Date.now());
+ });
+
+ return () => {
+ unsubscribe();
+ };
+ }, [navigation]);
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ Preloaded for: {endTime ? endTime - startTime : 'N/A'}ms
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Common actions preload" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ CommonActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home!
+ {
+ // highlight-next-line
+ navigation.preload('Profile', { user: 'jane' });
+ }}
+ >
+ Preload Profile
+
+ {
+ navigation.navigate('Profile', { user: 'jane' });
+ }}
+ >
+ Navigate to Profile
+
+
+ );
+}
+// codeblock-focus-end
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ const [startTime] = React.useState(Date.now());
+ const [endTime, setEndTime] = React.useState(null);
+
+ React.useEffect(() => {
+ const unsubscribe = navigation.addListener('focus', () => {
+ setEndTime(Date.now());
+ });
+
+ return () => {
+ unsubscribe();
+ };
+ }, [navigation]);
+
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ Preloaded for: {endTime ? endTime - startTime : 'N/A'}ms
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
+Preloading a screen means that the screen will be rendered in the background. All the components in the screen will be mounted and the `useEffect` hooks will be called. This can be useful when you want to improve the perceived performance by hiding the delay in mounting heavy components or loading data.
+
+Depending on the navigator, `preload` may work slightly differently:
+
+- In a stack navigator ([stack](stack-navigator.md), [native stack](native-stack-navigator.md)), the screen will be rendered off-screen and animated in when you navigate to it. If [`getId`](screen.md#id) is specified, it'll be used for the navigation to identify the preloaded screen.
+- In a tab or drawer navigator ([bottom tabs](bottom-tab-navigator.md), [material top tabs](material-top-tab-navigator.md), [drawer](drawer-navigator.md), etc.), the existing screen will be rendered as if `lazy` was set to `false`. Calling `preload` on a screen that is already rendered will not have any effect.
+
+When a screen is preloaded in a stack navigator, it will have a few limitations:
+
+- It can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.).
+- It can't update options with `navigation.setOptions`.
+- It can't listen to events from the navigator (e.g. `focus`, `tabPress`, etc.).
+
+The `navigation` object will be updated once you navigate to the screen. So if you have an event listener in a `useEffect` hook, and have a dependency on `navigation`, it will add any listeners when the screen is navigated to:
+
+```js
+React.useEffect(() => {
+ const unsubscribe = navigation.addListener('tabPress', () => {
+ // do something
+ });
+
+ return () => {
+ unsubscribe();
+ };
+}, [navigation]);
+```
+
+Similarly, for dispatching actions or updating options, you can check if the screen is focused before doing so:
+
+```js
+if (navigation.isFocused()) {
+ navigation.setOptions({ title: 'Updated title' });
+}
+```
+
### `setParams`
The `setParams` method lets us update the params (`route.params`) of the current screen. `setParams` works like React's `setState` - it shallow merges the provided params object with the current params.
-
+
+
-```js
-function ProfileScreen({ navigation: { setParams } }) {
- return (
-
- setParams({
- friends:
- route.params.friends[0] === 'Brent'
- ? ['Wojciech', 'Szymon', 'Jakub']
- : ['Brent', 'Satya', 'Michaś'],
- title:
- route.params.title === "Brent's Profile"
- ? "Lucy's Profile"
- : "Brent's Profile",
- })
- }
- title="Swap title and friends"
- />
+```js name="Navigation object setParams" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ friends: ['Brent', 'Satya', 'Michaś'],
+ title: "Brent's Profile",
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.friends[0]}
+ {route.params.friends[1]}
+ {route.params.friends[2]}
+ {
+ // highlight-start
+ navigation.setParams({
+ friends:
+ route.params.friends[0] === 'Brent'
+ ? ['Wojciech', 'Szymon', 'Jakub']
+ : ['Brent', 'Satya', 'Michaś'],
+ title:
+ route.params.title === "Brent's Profile"
+ ? "Lucy's Profile"
+ : "Brent's Profile",
+ });
+ // highlight-end
+ }}
+ >
+ Swap title and friends
+
+ navigation.goBack()}>Go back
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: {
+ screen: ProfileScreen,
+ options: ({ route }) => ({ title: route.params.title }),
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
+```
+
+
+
+
+```js name="Navigation object setParams" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ friends: ['Brent', 'Satya', 'Michaś'],
+ title: "Brent's Profile",
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.friends[0]}
+ {route.params.friends[1]}
+ {route.params.friends[2]}
+ {
+ // highlight-start
+ navigation.setParams({
+ friends:
+ route.params.friends[0] === 'Brent'
+ ? ['Wojciech', 'Szymon', 'Jakub']
+ : ['Brent', 'Satya', 'Michaś'],
+ title:
+ route.params.title === "Brent's Profile"
+ ? "Lucy's Profile"
+ : "Brent's Profile",
+ });
+ // highlight-end
+ }}
+ >
+ Swap title and friends
+
+ navigation.goBack()}>Go back
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+ ({ title: route.params.title })}
+ />
+
+
+ );
+}
+
+export default App;
+```
+
+
+
+
+### `replaceParams`
+
+The `replaceParams` method lets us replace the params (`route.params`) of the current screen with a new params object.
+
+
+
+
+```js name="Navigation object replaceParams" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ friends: ['Brent', 'Satya', 'Michaś'],
+ title: "Brent's Profile",
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.friends[0]}
+ {route.params.friends[1]}
+ {route.params.friends[2]}
+ {
+ // highlight-start
+ navigation.replaceParams({
+ friends:
+ route.params.friends[0] === 'Brent'
+ ? ['Wojciech', 'Szymon', 'Jakub']
+ : ['Brent', 'Satya', 'Michaś'],
+ title:
+ route.params.title === "Brent's Profile"
+ ? "Lucy's Profile"
+ : "Brent's Profile",
+ });
+ // highlight-end
+ }}
+ >
+ Swap title and friends
+
+ navigation.goBack()}>Go back
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: {
+ screen: ProfileScreen,
+ options: ({ route }) => ({ title: route.params.title }),
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
+```
+
+
+
+
+```js name="Navigation object replaceParams" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', {
+ friends: ['Brent', 'Satya', 'Michaś'],
+ title: "Brent's Profile",
+ });
+ }}
+ >
+ Go to Brents profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ Friends:
+ {route.params.friends[0]}
+ {route.params.friends[1]}
+ {route.params.friends[2]}
+ {
+ // highlight-start
+ navigation.replaceParams({
+ friends:
+ route.params.friends[0] === 'Brent'
+ ? ['Wojciech', 'Szymon', 'Jakub']
+ : ['Brent', 'Satya', 'Michaś'],
+ title:
+ route.params.title === "Brent's Profile"
+ ? "Lucy's Profile"
+ : "Brent's Profile",
+ });
+ // highlight-end
+ }}
+ >
+ Swap title and friends
+
+ navigation.goBack()}>Go back
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+ ({ title: route.params.title })}
+ />
+
+
);
}
+
+export default App;
```
+
+
+
### `setOptions`
The `setOptions` method lets us set screen options from within the component. This is useful if we need to use the component's props, state or context to configure our screen.
-
+
+
-```js
-function ProfileScreen({ navigation, route }) {
+```js name="Navigation object setOptions" snack
+import * as React from 'react';
+import { View, Text, TextInput } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', { title: "Brent's profile" });
+ }}
+ >
+ Go to Profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
const [value, onChangeText] = React.useState(route.params.title);
React.useEffect(() => {
+ // highlight-start
navigation.setOptions({
title: value === '' ? 'No title' : value,
});
+ // highlight-end
}, [navigation, value]);
return (
-
+
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: {
+ screen: ProfileScreen,
+ options: ({ route }) => ({ title: route.params.title }),
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
```
+
+
+
+```js name="Navigation object setOptions" snack
+import * as React from 'react';
+import { View, Text, TextInput } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ navigate('Profile', { title: "Brent's profile" })}>
+ Go to Profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ const [value, onChangeText] = React.useState(route.params.title);
+
+ React.useEffect(() => {
+ // highlight-start
+ navigation.setOptions({
+ title: value === '' ? 'No title' : value,
+ });
+ // highlight-end
+ }, [navigation, value]);
+
+ return (
+
+
+ navigation.goBack()}>Go back
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+ ({ title: route.params.title })}
+ />
+
+
+ );
+}
+
+export default App;
+```
+
+
+
+
Any options specified here are shallow merged with the options specified when defining the screen.
When using `navigation.setOptions`, we recommend specifying a placeholder in the screen's `options` prop and update it using `navigation.setOptions`. This makes sure that the delay for updating the options isn't noticeable to the user. It also makes it work with lazy-loaded screens.
@@ -215,22 +1577,164 @@ You can also use `React.useLayoutEffect` to reduce the delay in updating the opt
Screens can add listeners on the `navigation` object with the `addListener` method. For example, to listen to the `focus` event:
-
+
+
-```js
-function Profile({ navigation }) {
- React.useEffect(() => {
- const unsubscribe = navigation.addListener('focus', () => {
- // do something
- });
+```js name="Navigation events" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
- return unsubscribe;
- }, [navigation]);
+function SettingsScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Settings Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ React.useEffect(
+ () => navigation.addListener('focus', () => alert('Screen was focused')),
+ [navigation]
+ );
+
+ React.useEffect(
+ () => navigation.addListener('blur', () => alert('Screen was unfocused')),
+ [navigation]
+ );
+
+ return (
+
+ Profile Screen
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+// codeblock-focus-end
+
+const SettingsStack = createNativeStackNavigator({
+ screens: {
+ Settings: SettingsScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(SettingsStack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Navigation events" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
- return ;
+function SettingsScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Settings Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+// codeblock-focus-start
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ React.useEffect(
+ () => navigation.addListener('focus', () => alert('Screen was focused')),
+ [navigation]
+ );
+
+ React.useEffect(
+ () => navigation.addListener('blur', () => alert('Screen was unfocused')),
+ [navigation]
+ );
+
+ return (
+
+ Profile Screen
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+// codeblock-focus-end
+
+const SettingsStack = createNativeStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
See [Navigation events](navigation-events.md) for more details on the available events and the API usage.
### `isFocused`
@@ -348,12 +1852,28 @@ It accepts an optional ID parameter to refer to a specific parent navigator. For
To use an ID for a navigator, first pass a unique `id` prop:
+
+
+
```js
-
- {/* .. */}
-
+const Drawer = createDrawerNavigator({
+ id: 'LeftDrawer',
+ screens: {
+ /* content */
+ },
+});
+```
+
+
+
+
+```js
+{/* .. */}
```
+
+
+
Then when using `getParent`, instead of:
```js
diff --git a/versioned_docs/version-7.x/navigation-solutions-and-community-libraries.md b/versioned_docs/version-7.x/navigation-solutions-and-community-libraries.md
deleted file mode 100755
index 8a9c7d0afeb..00000000000
--- a/versioned_docs/version-7.x/navigation-solutions-and-community-libraries.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-id: navigation-solutions-and-community-libraries
-title: Navigation Solutions and Community Libraries
-sidebar_label: Navigation Solutions and Community Libraries
----
-
-:::note
-
-Libraries listed in this guide may not have been updated to work with the latest version of React Navigation. Please refer to the library's documentation to see which version of React Navigation it supports.
-
-:::
-
-## Solutions built on top of React Navigation
-
-### Solito
-
-A tiny wrapper around React Navigation and Next.js that lets you share navigation code across platforms. Also, it provides a set of patterns and examples for building cross-platform apps with React Native + Next.js.
-
-[Documentation](https://solito.dev/)
-
-[github.com/nandorojo/solito](https://github.com/nandorojo/solito)
-
-### Expo Router
-
-File-based router for React Native apps. With Expo Router pages are automatically generated by simply creating files in a project.
-
-[Documentation](https://expo.github.io/router/docs)
-
-[github.com/expo/router](https://github.com/expo/router)
-
-### Navio
-
-A navigation library built on top of React Navigation. It's main goal is to improve DX by building the app layout in one place and using the power of TypeScript to provide route names autocompletion.
-
-[github.com/kanzitelli/rn-navio](https://github.com/kanzitelli/rn-navio)
-
-[Demo on Snack](https://snack.expo.dev/@kanzitelli/rn-navio-snack)
-
-## Community libraries
-
-### react-native-screens
-
-This project aims to expose native navigation container components to React Native and React Navigation can integrate with it since version 2.14.0. Using `react-native-screens` brings several benefits, such as support for the ["reachability feature"](https://www.cnet.com/how-to/how-to-use-reachability-on-iphone-6-6-plus/) on iOS, and improved memory consumption on both platforms.
-
-[github.com/software-mansion/react-native-screens](https://github.com/software-mansion/react-native-screens)
-
-### react-navigation-header-buttons
-
-Helps you to render buttons in the navigation bar and handle the styling so you don't have to. It tries to mimic the appearance of native navbar buttons and attempts to offer a simple interface for you to interact with.
-
-[github.com/vonovak/react-navigation-header-buttons](https://github.com/vonovak/react-navigation-header-buttons)
-
-[Demo on expo](https://expo.io/@vonovak/navbar-buttons-demo)
-
-### react-navigation-props-mapper
-
-Provides simple HOCs that map react-navigation props to your screen components directly - ie. instead of `const user = this.props.route.params.activeUser`, you'd write `const user = this.props.activeUser`.
-
-[github.com/vonovak/react-navigation-props-mapper](https://github.com/vonovak/react-navigation-props-mapper)
diff --git a/versioned_docs/version-7.x/navigation-state.md b/versioned_docs/version-7.x/navigation-state.md
index 2ea0554b38c..43d2a59a7b5 100644
--- a/versioned_docs/version-7.x/navigation-state.md
+++ b/versioned_docs/version-7.x/navigation-state.md
@@ -4,7 +4,7 @@ title: Navigation state reference
sidebar_label: Navigation state
---
-The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as [resetting the state](navigation-actions.md#reset), [providing a custom initial state](navigation-container.md#initial-state) etc.
+The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as [resetting the state](navigation-actions.md#reset), [providing a custom initial state](navigation-container.md#initialstate) etc.
It's a JavaScript object which looks like this:
@@ -30,14 +30,14 @@ There are few properties present in every navigation state object:
- `routes` - List of route objects (screens) which are rendered in the navigator. It also represents the history in a stack navigator. There should be at least one item present in this array.
- `index` - Index of the focused route object in the `routes` array.
- `history` - A list of visited items. This is an optional property and not present in all navigators. For example, it's only present in tab and drawer navigators in the core. The shape of the items in the `history` array can vary depending on the navigator. There should be at least one item present in this array.
-- `stale` - A navigation state is assumed to be stale unless the `stale` property is explicitly set to `false`. This means that the state object needs to be ["rehydrated"](#partial-state-objects).
+- `stale` - A navigation state is assumed to be stale unless the `stale` property is explicitly set to `false`. This means that the state object needs to be ["rehydrated"](#stale-state-objects).
Each route object in a `routes` array may contain the following properties:
- `key` - Unique key of the screen. Created automatically or added while navigating to this screen.
- `name` - Name of the screen. Defined in navigator component hierarchy.
- `params` - An optional object containing params which is defined while navigating e.g. `navigate('Home', { sortBy: 'latest' })`.
-- `state` - An optional object containing the navigation state of a child navigator nested inside this screen.
+- `state` - An optional object containing the [stale navigation state](#stale-state-objects) of a child navigator nested inside this screen.
For example, a stack navigator containing a tab navigator nested inside it's home screen may have a navigation state object like this:
@@ -69,25 +69,28 @@ const state = {
It's important to note that even if there's a nested navigator, the `state` property on the `route` object is not added until a navigation happens, hence it's not guaranteed to exist.
-## Partial state objects
+## Stale state objects
-Earlier there was a mention of `stale` property in the navigation state. A stale navigation state means that the state object needs to be rehydrated or fixed or fixed up, such as adding missing keys, removing invalid screens etc. before being used. As a user, you don't need to worry about it, React Navigation will fix up any issues in a state object automatically unless `stale` is set to `false`. If you're writing a [custom router](custom-routers.md), the `getRehydratedState` method let's you write custom rehydration logic to fix up state objects.
+Earlier there was a mention of `stale` property in the navigation state. If the `stale` property is set to `true` or is missing, the state is assumed to be stale. A stale navigation state means that the state object may be partial, such as missing keys or routes, contain invalid routes, or may not be up-to-date. A stale state can be a result of [deep linking](deep-linking.md), r[estoring from a persisted state](state-persistence.md) etc.
-This also applies to the `index` property: `index` should be the last route in a stack, and if a different value was specified, React Navigation fixes it. For example, if you wanted to reset your app's navigation state to have it display the `Profile` route, and have the `Home` route displayed upon going back, and did the below,
+If you're accessing the navigation state of a navigator using the built-in APIs such as [`useNavigationState()`](use-navigation-state.md), [`navigation.getState()`](navigation-object.md#getstate) etc., the state object is guaranteed to be complete and not stale. However, if you try to access a child navigator's state with the `state` property on the `route` object, it maybe a stale or partial state object. So it's not recommended to use this property directly.
+
+Using the [`ref.getRootState()`](navigation-container.md#getrootstate) API will always return a complete and up-to-date state object for the current navigation tree, including any nested child navigators.
+
+When React Navigation encounters stale or partial state, it will automatically fix it up before using it. This includes adding missing keys, removing any invalid routes, ensuring the `index` is correct etc. This process of fixing stale state is called **rehydration**. If you're writing a [custom router](custom-routers.md), the `getRehydratedState` method lets you write custom rehydration logic to fix up state objects.
+
+For example, `index` should be the last route in a stack, and if a different value was specified, React Navigation fixes it. For example, if you wanted to reset your app's navigation state to have it display the `Profile` route, and have the `Home` route displayed upon going back, and dispatched the following action:
```js
navigation.reset({
index: 0,
- routes: [
- { name: 'Home' },
- { name: 'Profile' }
- ],
+ routes: [{ name: 'Home' }, { name: 'Profile' }],
});
```
-React Navigation would correct `index` to 1, and display the route and perform navigation as intended.
+React Navigation would correct `index` to `1` before the routes are displayed.
-This feature comes handy when doing operations such as [reset](navigation-actions.md#reset), [providing a initial state](navigation-container.md#initial-state) etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a `routes` array without any keys and React Navigation will automatically add everything that's needed to make it work:
+This feature comes handy when doing operations such as [reset](navigation-actions.md#reset), [providing a initial state](navigation-container.md#initialstate) etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a `routes` array without any keys and React Navigation will automatically add everything that's needed to make it work:
```js
const state = {
@@ -121,4 +124,4 @@ If you want React Navigation to fix invalid state, you need to make sure that yo
:::
-When you're providing a state object in [`initialState`](navigation-container.md#initial-state), React Navigation will always assume that it's a stale state object, which makes sure that things like state persistence work smoothly without extra manipulation of the state object.
+When you're providing a state object in [`initialState`](navigation-container.md#initialstate), React Navigation will always assume that it's a stale state object, since navigation configuration may have changed since the last time. This makes sure that things like [state persistence](state-persistence.md) work smoothly without extra manipulation of the state object.
diff --git a/versioned_docs/version-7.x/navigator.md b/versioned_docs/version-7.x/navigator.md
new file mode 100644
index 00000000000..f34638f4be2
--- /dev/null
+++ b/versioned_docs/version-7.x/navigator.md
@@ -0,0 +1,463 @@
+---
+id: navigator
+title: Navigator
+sidebar_label: Navigator
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+A navigator is responsible for managing and rendering a set of screens. It can be created using the `createXNavigator` functions, e.g. [`createStackNavigator`](stack-navigator.md), [`createNativeStackNavigator`](native-stack-navigator.md), [`createBottomTabNavigator`](bottom-tab-navigator.md), [`createMaterialTopTabNavigator`](material-top-tab-navigator.md), [`createDrawerNavigator`](drawer-navigator.md) etc.:
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+
+
+
+In addition to the built-in navigators, it's also possible to build your custom navigators or use third-party navigators. See [custom navigators](custom-navigators.md) for more details.
+
+## Configuration
+
+Different navigators accept different configuration options. You can find the list of options for each navigator in their respective documentation.
+
+There is a set of common configurations that are shared across all navigators:
+
+### ID
+
+Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator.
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ // highlight-next-line
+ id: 'RootStack',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+
+
+
+### Initial route name
+
+The name of the route to render on the first load of the navigator.
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ // highlight-next-line
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+
+
+
+### Layout
+
+A layout is a wrapper around the navigator. It can be useful for augmenting the navigators with additional UI with a wrapper.
+
+The difference from adding a wrapper around the navigator manually is that the code in a layout callback has access to the navigator's state, options etc.
+
+It takes a function that returns a React element:
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ // highlight-start
+ layout: ({ children, state, descriptors, navigation }) => (
+
+
+ {children}
+
+ ),
+ // highlight-end
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+ (
+
+
+ {children}
+
+ )}
+ // highlight-end
+ >
+
+
+
+ );
+}
+```
+
+
+
+
+### Screen options
+
+Default options to use for all the screens in the navigator. It accepts either an object or a function returning an object:
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ // highlight-start
+ screenOptions: {
+ headerShown: false,
+ },
+ // highlight-end
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+
+
+
+
+ );
+}
+```
+
+
+
+
+See [Options for screens](screen-options.md) for more details and examples.
+
+### Screen listeners
+
+Event listeners can be used to subscribe to various events emitted for the screen. See [`screenListeners` prop on the navigator](navigation-events.md#screenlisteners-prop-on-the-navigator) for more details.
+
+### Screen layout
+
+A screen layout is a wrapper around each screen in the navigator. It makes it easier to provide things such as an error boundary and suspense fallback for all screens in the navigator, or wrap each screen with additional UI.
+
+It takes a function that returns a React element:
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ // highlight-start
+ screenLayout: ({ children }) => (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ ),
+ // highlight-end
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+ (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ )}
+ // highlight-end
+ >
+
+
+
+ );
+}
+```
+
+
+
+
+### Router
+
+:::warning
+
+This API is experimental and may change in a minor release.
+
+:::
+
+Routers can be customized with the `UNSTABLE_router` prop on navigator to override how navigation actions are handled.
+
+It takes a function that receives the original router and returns an object with overrides:
+
+
+
+
+```js
+const MyStack = createNativeStackNavigator({
+ // highlight-start
+ UNSTABLE_router: (original) => ({
+ getStateForAction(state, action) {
+ if (action.type === 'SOME_ACTION') {
+ // Custom logic
+ }
+
+ // Fallback to original behavior
+ return original.getStateForAction(state, action);
+ },
+ }),
+ // highlight-end
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
+```js
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+ ({
+ getStateForAction(state, action) {
+ if (action.type === 'SOME_ACTION') {
+ // Custom logic
+ }
+
+ // Fallback to original behavior
+ return original.getStateForAction(state, action);
+ },
+ })}
+ // highlight-end
+ >
+
+
+
+ );
+}
+```
+
+
+
+
+The function passed to `UNSTABLE_router` **must be a pure function and cannot reference outside dynamic variables**.
+
+The overrides object is shallow merged with the original router. So you don't need to specify all properties of the router, only the ones you want to override.
+
+See [custom routers](custom-routers.md) for more details on routers.
+
+### Route names change behavior
+
+:::warning
+
+This API is experimental and may change in a minor release.
+
+:::
+
+When the list of available routes in a navigator changes dynamically, e.g. based on conditional rendering, looping over data from an API etc., the navigator needs to update the [navigation state](navigation-state.md) according to the new list of routes.
+
+By default, it works as follows:
+
+- Any routes not present in the new available list of routes are removed from the navigation state
+- If the currently focused route is still present in the new available list of routes, it remains focused.
+- If the currently focused route has been removed, but the navigation state has other routes that are present in the new available list, the first route in from the list of rendered routes becomes focused.
+- If none of the routes in the navigation state are present in the new available list of routes, one of the following things can happen based on the `UNSTABLE_routeNamesChangeBehavior` prop:
+ - `'firstMatch'` - The first route defined in the new list of routes becomes focused. This is the default behavior based on [`getStateForRouteNamesChange`](custom-routers.md) in the router.
+ - `'lastUnhandled'` - The last state that was unhandled due to conditional rendering is restored.
+
+Example cases where state might have been unhandled:
+
+- Opened a deep link to a screen, but a login screen was shown.
+- Navigated to a screen containing a navigator, but a different screen was shown.
+- Reset the navigator to a state with different routes not matching the available list of routes.
+
+In these cases, specifying `'lastUnhandled'` will reuse the unhandled state if present. If there's no unhandled state, it will fallback to `'firstMatch'` behavior.
+
+Caveats:
+
+- Direct navigation is only handled for `NAVIGATE` actions.
+- Unhandled state is restored only if the current state becomes invalid, i.e. it doesn't contain any currently defined screens.
+
+Example usage:
+
+
+
+
+```js
+const RootStack = createNativeStackNavigator({
+ // highlight-next-line
+ UNSTABLE_routeNamesChangeBehavior: 'lastUnhandled',
+ screens: {
+ Home: {
+ if: useIsSignedIn,
+ screen: HomeScreen,
+ },
+ SignIn: {
+ if: useIsSignedOut,
+ screen: SignInScreen,
+ options: {
+ title: 'Sign in',
+ },
+ },
+ },
+});
+```
+
+
+
+
+```js
+
+ {isSignedIn ? (
+
+ ) : (
+
+ )}
+
+```
+
+
+
+
+The most common use case for this is to [show the correct screen based on authentication based on deep link](auth-flow.md#handling-deep-links-after-auth).
diff --git a/versioned_docs/version-7.x/nesting-navigators.md b/versioned_docs/version-7.x/nesting-navigators.md
index b74e933c305..4264cc57dcb 100755
--- a/versioned_docs/version-7.x/nesting-navigators.md
+++ b/versioned_docs/version-7.x/nesting-navigators.md
@@ -12,15 +12,16 @@ Nesting navigators means rendering a navigator inside a screen of another naviga
-```js name="Nested navigators" snack version=7
+```js name="Nested navigators" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function ProfileScreen() {
return (
@@ -36,10 +37,9 @@ function FeedScreen() {
return (
Feed Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -84,12 +84,13 @@ export default function App() {
-```js name="Nested navigators" snack version=7
+```js name="Nested navigators" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function ProfileScreen() {
return (
@@ -105,10 +106,9 @@ function FeedScreen() {
return (
Feed Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -189,7 +189,7 @@ If you want to achieve this behavior, see the guide for [screen options with nes
For example, any `params` passed to a screen in a nested navigator are in the `route` object of that screen and aren't accessible from a screen in a parent or child navigator.
-If you need to access params of the parent screen from a child screen, you can use [React Context](https://reactjs.org/docs/context.html) to expose params to children.
+If you need to access params of the parent screen from a child screen, you can use [React Context](https://react.dev/reference/react/useContext) to expose params to children.
### Navigation actions are handled by current navigator and bubble up if couldn't be handled
@@ -216,15 +216,16 @@ To receive events from the parent navigator, you can explicitly listen to parent
-```js name="Events from parent" snack version=7
+```js name="Events from parent" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function ProfileScreen() {
return (
@@ -240,10 +241,9 @@ function FeedScreen() {
return (
Feed Screen
- navigation.navigate('Messages')}
- />
+ navigation.navigate('Messages')}>
+ Go to Messages
+
);
}
@@ -301,12 +301,13 @@ export default function App() {
-```js name="Events from parent" snack version=7
+```js name="Events from parent" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function ProfileScreen() {
return (
@@ -322,10 +323,9 @@ function FeedScreen() {
return (
Feed Screen
- navigation.navigate('Messages')}
- />
+ navigation.navigate('Messages')}>
+ Go to Messages
+
);
}
@@ -410,15 +410,16 @@ Consider the following example:
-```js name="Navigating to nested screen" snack version=7
+```js name="Navigating to nested screen" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -426,11 +427,12 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('More')} />
+ navigation.navigate('More')}>Go to More
navigation.navigate('More', { screen: 'Messages' })}
- />
+ >
+ Go to Messages
+
);
}
@@ -441,7 +443,7 @@ function FeedScreen() {
return (
Feed Screen
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -452,7 +454,7 @@ function MessagesScreen() {
return (
Messages Screen
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -488,12 +490,13 @@ export default function App() {
-```js name="Navigating to nested screen" snack version=7
+```js name="Navigating to nested screen" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -501,11 +504,12 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('More')} />
+ navigation.navigate('More')}>Go to More
navigation.navigate('More', { screen: 'Messages' })}
- />
+ >
+ Go to Messages
+
);
}
@@ -516,7 +520,7 @@ function FeedScreen() {
return (
Feed Screen
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -527,7 +531,7 @@ function MessagesScreen() {
return (
Messages Screen
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -592,15 +596,16 @@ You can also pass params by specifying a `params` key:
-```js name="Navigating to nested screen" snack version=7
+```js name="Navigating to nested screen" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -609,7 +614,6 @@ function HomeScreen() {
Home Screen
// codeblock-focus-start
@@ -619,7 +623,9 @@ function HomeScreen() {
})
// codeblock-focus-end
}
- />
+ >
+ Go to Messages
+
);
}
@@ -630,7 +636,7 @@ function FeedScreen() {
return (
Feed Screen
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -642,7 +648,7 @@ function MessagesScreen({ route }) {
Messages Screen
User: {route.params.user}
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -676,12 +682,13 @@ export default function App() {
-```js name="Navigating to nested screen" snack version=7
+```js name="Navigating to nested screen" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function HomeScreen() {
const navigation = useNavigation();
@@ -690,7 +697,6 @@ function HomeScreen() {
Home Screen
// codeblock-focus-start
@@ -700,7 +706,9 @@ function HomeScreen() {
})
// codeblock-focus-end
}
- />
+ >
+ Go to Messages
+
);
}
@@ -711,7 +719,7 @@ function FeedScreen() {
return (
Feed Screen
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -723,7 +731,7 @@ function MessagesScreen({ route }) {
Messages Screen
User: {route.params.user}
- navigation.goBack()} />
+ navigation.goBack()}>Go back
);
}
@@ -783,6 +791,12 @@ navigation.navigate('Home', {
In the above case, you're navigating to the `Media` screen, which is in a navigator nested inside the `Sound` screen, which is in a navigator nested inside the `Settings` screen.
+:::warning
+
+The `screen` and related params are reserved for internal use and are managed by React Navigation. While you can access `route.params.screen` etc. in the parent screens, relying on them may lead to unexpected behavior.
+
+:::
+
### Rendering initial route defined in the navigator
By default, when you navigate a screen in the nested navigator, the specified screen is used as the initial screen and the `initialRouteName` prop on the navigator is ignored.
@@ -809,15 +823,16 @@ For example:
-```js name="Nested navigators" snack version=7
+```js name="Nested navigators" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function ProfileScreen() {
return (
@@ -833,10 +848,9 @@ function FeedScreen() {
return (
Feed Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -881,12 +895,13 @@ export default function App() {
-```js name="Nested navigators" snack version=7
+```js name="Nested navigators" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function ProfileScreen() {
return (
@@ -902,10 +917,9 @@ function FeedScreen() {
return (
Feed Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -1039,7 +1053,7 @@ We recommend to reduce nesting navigators to minimal. Try to achieve the behavio
- Nesting same type of navigators (e.g. tabs inside tabs, drawer inside drawer etc.) might lead to a confusing UX
- With excessive nesting, code becomes difficult to follow when navigating to nested screens, configuring deep link etc.
-Think of nesting navigators as a way to achieve the UI you want rather than a way to organize your code. If you want to create separate group of screens for organization, instead of using separate navigators, you can use the [`Group`](group.md) component for dynamic configuration or [`groups` property](static-api-reference.md#groups) for static configuration.
+Think of nesting navigators as a way to achieve the UI you want rather than a way to organize your code. If you want to create separate group of screens for organization, instead of using separate navigators, you can use the [`Group`](group.md) component for dynamic configuration or [`groups` property](static-configuration.md#groups) for static configuration.
diff --git a/versioned_docs/version-7.x/next-steps.md b/versioned_docs/version-7.x/next-steps.md
index af25158836b..6efc2fb1717 100755
--- a/versioned_docs/version-7.x/next-steps.md
+++ b/versioned_docs/version-7.x/next-steps.md
@@ -4,10 +4,21 @@ title: Next steps
sidebar_label: Next steps
---
-You are now familiar with how to create a stack navigator, configure it on your screen components, navigate between routes, and display modals. Stack navigators and their related APIs will be the most frequently used tools in your React Navigation toolbelt, but there are problems that they don't solve. For example, you can't build tab-based navigation using a stack navigator — for that, you need to use a [TabNavigator](tab-based-navigation.md).
+You are now familiar with how to create a stack navigator, configure it on your screen components, navigate between routes, and display [modals](modal.md). Stack navigators and their related APIs will be the most frequently used tools in your React Navigation toolbelt, but there are problems that they don't solve. For example, you can't build tab-based navigation using a stack navigator — for that, you need to use a [Bottom Tabs Navigator](bottom-tab-navigator.md).
-The rest of the documentation is organized around specific use cases, so you can jump between the sections under "Guides" as the need arises (but it also wouldn't hurt you to familiarize yourself with them pre-emptively!).
+You can check out the **"Navigators"** section in the sidebar to learn more about the different navigators available in React Navigation.
-While most users won't need to do this, if you are curious and want to learn more about how React Navigation works, it's recommended to work through the "Build your own Navigator" section.
+The rest of the documentation is organized around specific use cases, so you can jump between the sections under **"Guides"** as the need arises (but it also wouldn't hurt you to familiarize yourself with them pre-emptively!).
+
+Some of the guides you may want to check out are:
+
+- [Authentication flows](auth-flow.md): How to handle authentication flows in your app.
+- [Supporting safe areas](handling-safe-area.md): How to handle safe areas such as statusbar in your app.
+- [Deep linking](deep-linking.md): How to handle deep linking and universal links in your app.
+- [Themes](themes.md): How to customize the look and feel of various UI elements.
+- [Testing with Jest](testing.md): How to test your navigation components.
+- [Configuring TypeScript](typescript.md): How to configure TypeScript for React Navigation.
+
+While most users won't need to do this, if you are curious and want to learn more about how React Navigation works, it's recommended to work through the [Navigation State reference](navigation-state.md) and [Build your own Navigator](custom-navigators.md) sections.
Good luck!
diff --git a/versioned_docs/version-7.x/params.md b/versioned_docs/version-7.x/params.md
index 11ceea511de..4905bd4ef55 100755
--- a/versioned_docs/version-7.x/params.md
+++ b/versioned_docs/version-7.x/params.md
@@ -22,14 +22,15 @@ We recommend that the params you pass are JSON-serializable. That way, you'll be
:::
-```js name="Passing params" snack version=7
+```js name="Passing params" snack
import * as React from 'react';
-import { Button, View, Text } from 'react-native';
+import { View, Text } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
function HomeScreen() {
@@ -39,7 +40,6 @@ function HomeScreen() {
Home Screen
{
/* 1. Navigate to the Details route with params */
// highlight-start
@@ -49,7 +49,9 @@ function HomeScreen() {
});
// highlight-end
}}
- />
+ >
+ Go to Details
+
);
}
@@ -67,7 +69,6 @@ function DetailsScreen({ route }) {
itemId: {JSON.stringify(itemId)}
otherParam: {JSON.stringify(otherParam)}
// highlight-start
@@ -76,9 +77,11 @@ function DetailsScreen({ route }) {
})
// highlight-end
}
- />
- navigation.navigate('Home')} />
- navigation.goBack()} />
+ >
+ Go to Details... again
+
+ navigation.navigate('Home')}>Go to Home
+ navigation.goBack()}>Go back
);
}
@@ -98,7 +101,9 @@ export default function App() {
}
```
-
+
+
+
## Initial params
@@ -120,8 +125,6 @@ You can also pass some initial params to a screen. If you didn't specify any par
-
-
```js
Home Screen
itemId: {JSON.stringify(itemId)}
// codeblock-focus-start
@@ -167,7 +170,9 @@ function HomeScreen({ route }) {
})
// codeblock-focus-end
}
- />
+ >
+ Update param
+
);
}
@@ -188,9 +193,11 @@ export default function App() {
}
```
+The `setParams` method merges the new params with the existing ones. To replace the existing params, you can use [`replaceParams`](navigation-object.md#replaceparams) instead.
+
:::note
-Avoid using `setParams` to update screen options such as `title` etc. If you need to update options, use [`setOptions`](navigation-object.md#setoptions) instead.
+Avoid using `setParams` or `replaceParams` to update screen options such as `title` etc. If you need to update options, use [`setOptions`](navigation-object.md#setoptions) instead.
:::
@@ -200,14 +207,15 @@ Params aren't only useful for passing some data to a new screen, but they can al
To achieve this, you can use the `popTo` method to go back to the previous screen as well as pass params to it:
-```js name="Passing params back" snack version=7
+```js name="Passing params back" snack
import * as React from 'react';
-import { Text, View, TextInput, Button } from 'react-native';
+import { Text, View, TextInput } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
function HomeScreen({ route }) {
@@ -226,10 +234,9 @@ function HomeScreen({ route }) {
return (
- navigation.navigate('CreatePost')}
- />
+ navigation.navigate('CreatePost')}>
+ Create post
+
Post: {route.params?.post}
);
@@ -249,13 +256,14 @@ function CreatePostScreen({ route }) {
onChangeText={setPostText}
/>
{
// Pass params back to home screen
// highlight-next-line
navigation.popTo('Home', { post: postText });
}}
- />
+ >
+ Done
+
>
);
}
@@ -275,21 +283,26 @@ export default function App() {
}
```
+
+
+
+
Here, after you press "Done", the home screen's `route.params` will be updated to reflect the post text that you passed in `navigate`.
## Passing params to a nested screen
If you have nested navigators, you need to pass params a bit differently. For example, say you have a navigator inside the `More` screen and want to pass params to the `Settings` screen inside that navigator. Then you can pass params as the following:
-```js name="Passing params to nested screen" snack version=7
+```js name="Passing params to nested screen" snack
import * as React from 'react';
-import { Text, View, TextInput, Button } from 'react-native';
+import { Text, View, TextInput } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Button } from '@react-navigation/elements';
function SettingsScreen({ route }) {
const navigation = useNavigation();
@@ -299,10 +312,9 @@ function SettingsScreen({ route }) {
Settings Screen
userParam: {JSON.stringify(user)}
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -322,7 +334,6 @@ function HomeScreen() {
Home Screen
// codeblock-focus-start
@@ -332,7 +343,9 @@ function HomeScreen() {
})
// codeblock-focus-end
}
- />
+ >
+ Go to Settings
+
);
}
@@ -360,11 +373,22 @@ export default function App() {
See [Nesting navigators](nesting-navigators.md) for more details on nesting.
+## Reserved param names
+
+Some param names are reserved by React Navigation as part of the API for nested navigators. The list of the reserved param names are as follows:
+
+- `screen`
+- `params`
+- `initial`
+- `state`
+
+You should avoid using these param names in your code unless navigating to a screen containing a nested navigator. Otherwise it will result in unexpected behavior, such as the screen not being able to access the params you passed. If you need to pass data to a nested screen, use a different names for the param.
+
## What should be in params
-It's important to understand what kind of data should be in params. Params are like options for a screen. They should only contain information to configure what's displayed in the screen. Avoid passing the full data which will be displayed on the screen itself (e.g. pass a user id instead of user object). Also avoid passing data which is used by multiple screens, such data should be in a global store.
+Params are essentially options for a screen. They should contain the minimal data required to show a screen, nothing more. If the data is used by multiple screens, it should be in a global store or global cache. Params is not designed for state management.
-You can also think of the route object like a URL. If your screen had a URL, what should be in the URL? Params shouldn't contain data that you think should not be in the URL. This often means that you should keep as little data as possible needed to determine what the screen is. Think of visiting a shopping website, when you are seeing product listings, the URL usually contains category name, type of sort, any filters etc., it doesn't contain the actual list of products displayed on the screen.
+You can think of the route object as a URL. If your screen had a URL, what should be in the URL? The same principles apply to params. Think of visiting a shopping website; when you see product listings, the URL usually contains category name, type of sort, any filters etc., not the actual list of products displayed on the screen.
For example, say if you have a `Profile` screen. When navigating to it, you might be tempted to pass the user object in the params:
@@ -382,13 +406,14 @@ navigation.navigate('Profile', {
This looks convenient and lets you access the user objects with `route.params.user` without any extra work.
-However, this is an anti-pattern. Data such as user objects should be in your global store instead of the navigation state. Otherwise, you have the same data duplicated in multiple places. This can lead to bugs such as the profile screen showing outdated data even if the user object has changed after navigation.
-
-It also becomes problematic to link to the screen via deep linking or on the Web, since:
+However, this is an anti-pattern. There are many reasons why this is a bad idea:
-1. The URL is a representation of the screen, so it also needs to contain the params, i.e. full user object, which can make the URL very long and unreadable
-2. Since the user object is in the URL, it's possible to pass a random user object representing a user which doesn't exist or has incorrect data in the profile
-3. If the user object isn't passed, or improperly formatted, this could result in crashes as the screen won't know how to handle it
+- The same data is duplicated in multiple places. This can lead to bugs such as the profile screen showing outdated data even if the user object has changed after navigation.
+- Each screen that navigates to the `Profile` screen now needs to know how to fetch the user object - which increases the complexity of the code.
+- URLs to the screen (browser URL on the web, or deep links on native) will contain the user object. This is problematic:
+ 1. Since the user object is in the URL, it's possible to pass a random user object representing a user that doesn't exist or has incorrect data in the profile.
+ 2. If the user object isn't passed or improperly formatted, this could result in crashes as the screen won't know how to handle it.
+ 3. The URL can become very long and unreadable.
A better way is to pass only the ID of the user in params:
@@ -396,11 +421,11 @@ A better way is to pass only the ID of the user in params:
navigation.navigate('Profile', { userId: 'jane' });
```
-Now, you can use the passed `userId` to grab the user from your global store. This eliminates a host of issues such as outdated data, or problematic URLs.
+Now, you can use the passed `userId` to grab the user from your global cache or fetch it from the API. Using a library such as [React Query](https://tanstack.com/query/) can simplify this process since it makes it easy to fetch and cache your data. This approach helps to avoid the problems mentioned above.
Some examples of what should be in params are:
-1. IDs like user id, item id etc., e.g. `navigation.navigate('Profile', { userId: 'Jane' })`
+1. IDs such as user id, item id etc., e.g. `navigation.navigate('Profile', { userId: 'Jane' })`
2. Params for sorting, filtering data etc. when you have a list of items, e.g. `navigation.navigate('Feeds', { sortBy: 'latest' })`
3. Timestamps, page numbers or cursors for pagination, e.g. `navigation.navigate('Chat', { beforeTime: 1603897152675 })`
4. Data to fill inputs on a screen to compose something, e.g. `navigation.navigate('ComposeTweet', { title: 'Hello world!' })`
@@ -409,8 +434,9 @@ In essence, pass the least amount of data required to identify a screen in param
## Summary
-- `navigate` and `push` accept an optional second argument to let you pass parameters to the route you are navigating to. For example: `navigation.navigate('RouteName', { paramName: 'value' })`.
-- You can read the params through `route.params` inside a screen
-- You can update the screen's params with `navigation.setParams`
-- Initial params can be passed via the `initialParams` prop on `Screen`
+- [`navigate`](navigation-actions.md#navigate) and [`push`](stack-actions.md#push) accept an optional second argument to let you pass parameters to the route you are navigating to. For example: `navigation.navigate('RouteName', { paramName: 'value' })`.
+- You can read the params through [`route.params`](route-object.md) inside a screen
+- You can update the screen's params with [`navigation.setParams`](navigation-object.md#setparams) or [`navigation.replaceParams`](navigation-object.md#replaceparams)
+- Initial params can be passed via the [`initialParams`](screen.md#initial-params) prop on `Screen` or in the navigator config
- Params should contain the minimal data required to show a screen, nothing more
+- Some [param names are reserved](#reserved-param-names) by React Navigation and should be avoided
diff --git a/versioned_docs/version-7.x/preventing-going-back.md b/versioned_docs/version-7.x/preventing-going-back.md
index e777783bca0..0d727fdc033 100644
--- a/versioned_docs/version-7.x/preventing-going-back.md
+++ b/versioned_docs/version-7.x/preventing-going-back.md
@@ -4,93 +4,93 @@ title: Preventing going back
sidebar_label: Preventing going back
---
-Sometimes you may want to prevent the user from leaving a screen, for example, if there are unsaved changes, you might want to show a confirmation dialog. You can achieve it by using the `beforeRemove` event.
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
-The event listener receives the `action` that triggered it. You can dispatch this action again after confirmation, or check the action object to determine what to do.
+Sometimes you may want to prevent the user from leaving a screen to avoid losing unsaved changes. There are a couple of things you may want to do in this case:
-Example:
+## Prevent the user from leaving the screen
-
+The `usePreventRemove` hook allows you to prevent the user from leaving a screen. See the [`usePreventRemove`](use-prevent-remove.md) docs for more details.
-```js
-function EditText({ navigation }) {
- const [text, setText] = React.useState('');
- const hasUnsavedChanges = Boolean(text);
-
- React.useEffect(
- () =>
- navigation.addListener('beforeRemove', (e) => {
- if (!hasUnsavedChanges) {
- // If we don't have unsaved changes, then we don't need to do anything
- return;
- }
-
- // Prevent default behavior of leaving the screen
- e.preventDefault();
-
- // Prompt the user before leaving the screen
- Alert.alert(
- 'Discard changes?',
- 'You have unsaved changes. Are you sure to discard them and leave the screen?',
- [
- { text: "Don't leave", style: 'cancel', onPress: () => {} },
- {
- text: 'Discard',
- style: 'destructive',
- // If the user confirmed, then we dispatch the action we blocked earlier
- // This will continue the action that had triggered the removal of the screen
- onPress: () => navigation.dispatch(e.data.action),
- },
- ]
- );
- }),
- [navigation, hasUnsavedChanges]
- );
-
- return (
-
- );
-}
-```
+
+Previous approach
Previously, the way to do this was to:
-- Override back button in header
+- Override the back button in the header
- Disable back swipe gesture
- Override system back button/gesture on Android
-However, this approach has many important differences in addition to being less code:
+However, using the hook has many important differences in addition to being less code:
- It's not coupled to any specific buttons, going back from custom buttons will trigger it as well
-- It's not coupled to any specific actions, any action that removes the route from state will trigger it
-- It works across nested navigators, e.g. if the screen is being removed due to an action in parent navigator
-- User can still swipe back in the stack navigator, however, the swipe will be cancelled if the event was prevented
+- It's not coupled to any specific actions, any action that removes the route from the state will trigger it
+- It works across nested navigators, e.g. if the screen is being removed due to an action in the parent navigator
+- The user can still swipe back in the stack navigator, however, the swipe will be canceled if the event is prevented
- It's possible to continue the same action that triggered the event
-## Limitations
+
-There are couple of limitations to be aware of when using the `beforeRemove` event. The event is **only** triggered whenever a screen is being removed due to a navigation state change. For example:
+## Prevent the user from leaving the app
-- The user pressed back button on a screen in a stack.
-- The user performed a swipe back gesture.
-- Some action such as `pop` or `reset` was dispatched which removes the screen from the state.
+To be able to prompt the user before they leave the app on Android, you can use the `BackHandler` API from React Native:
-This event is **not** triggered when a screen is being unfocused but not removed. For example:
+```js
+import { Alert, BackHandler } from 'react-native';
+
+// ...
+
+React.useEffect(() => {
+ const onBackPress = () => {
+ Alert.alert(
+ 'Exit App',
+ 'Do you want to exit?',
+ [
+ {
+ text: 'Cancel',
+ onPress: () => {
+ // Do nothing
+ },
+ style: 'cancel',
+ },
+ { text: 'YES', onPress: () => BackHandler.exitApp() },
+ ],
+ { cancelable: false }
+ );
+
+ return true;
+ };
+
+ const backHandler = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ onBackPress
+ );
+
+ return () => backHandler.remove();
+}, []);
+```
-- The user pushed a new screen on top of the screen with the listener in a stack.
-- The user navigated from one tab/drawer screen to another tab/drawer screen.
+On the Web, you can use the `beforeunload` event to prompt the user before they leave the browser tab:
-The event is also **not** triggered when the user is exiting the screen due to actions not controlled by the navigation state:
+```js
+React.useEffect(() => {
+ const onBeforeUnload = (event) => {
+ // Prevent the user from leaving the page
+ event.preventDefault();
+ event.returnValue = true;
+ };
+
+ window.addEventListener('beforeunload', onBeforeUnload);
+
+ return () => {
+ window.removeEventListener('beforeunload', onBeforeUnload);
+ };
+}, []);
+```
-- The user closes the app (e.g. by pressing the back button on the home screen, closing the tab in the browser, closing it from app switcher etc.). You can additionally use [`hardwareBackPress`](https://reactnative.dev/docs/backhandler) event on Android, [`beforeunload`](https://developer.mozilla.org/en-US/docs/web/api/window/beforeunload_event) event on Web etc. to handle some of these cases.
-- A screen gets unmounted due to conditional rendering, or due to a parent component being unmounted.
-- A screen gets unmounted due to usage of `unmountOnBlur` options with [`@react-navigation/bottom-tabs`](bottom-tab-navigator.md), [`@react-navigation/drawer`](drawer-navigator.md) etc.
+:::warning
-In addition to the above scenarios, this feature also doesn't work properly with [`@react-navigation/native-stack`](native-stack-navigator.md). To make this work, you need to:
+The user can still close the app by swiping it away from the app switcher or closing the browser tab. Or the app can be closed by the system due to low memory or other reasons. It's also not possible to prevent leaving the app on iOS. We recommend persisting the data and restoring it when the app is opened again instead of prompting the user before they leave the app.
-- Disable the swipe gesture for the screen (`gestureEnabled: false`).
-- Override the native back button in the header with a custom back button (`headerLeft: (props) => `).
+:::
diff --git a/versioned_docs/version-7.x/redux-integration.md b/versioned_docs/version-7.x/redux-integration.md
deleted file mode 100755
index 5f6b54d4a2b..00000000000
--- a/versioned_docs/version-7.x/redux-integration.md
+++ /dev/null
@@ -1,90 +0,0 @@
----
-id: redux-integration
-title: Redux integration
-sidebar_label: Redux integration
----
-
-It is extremely easy to use Redux in an app with React Navigation. It's basically no different than without React Navigation.
-
-```js
-import { Provider } from 'react-redux';
-import { NavigationContainer } from '@react-navigation/native';
-
-// Render the app container component with the provider around it
-export default function App() {
- return (
-
-
- {/* Screen configuration */}
-
-
- );
-}
-```
-
-Notice that we wrap our components in a `Provider` like we'd normally do with `react-redux`. Ta da! Now feel free to use `connect` throughout your app.
-
-### Use a component that is `connect`ed in `options`
-
-Create a component, `connect` it to the store, then use that component in the `title`.
-
-
-
-```js
-function Counter({ value }) {
- return Count: {value} ;
-}
-
-const CounterContainer = connect(state => ({ value: state.count }))(Counter);
-```
-
-```js
- }}
-/>
-```
-
-### Pass the state you care about as a param to the screen
-
-If the value isn't expected to change, you can just pass it from a connected component to the other screen as a param.
-
-```js
-
- props.navigation.navigate('StaticCounter', {
- count,
- })
- }
-/>
-```
-
-```js
-function StaticCounter({ route }) {
- return (
-
- {route.params.count}
-
- );
-}
-```
-
-So our component will look like this:
-
-
-
-```js
- ({ title: route.params.count })}
-/>
-```
-
-## Can I store the navigation state in Redux too?
-
-This is not possible. We don't support it because it's too easy to shoot yourself in the foot and slow down / break your app.
-
-However it's possible to use [`redux-devtools-extension`](https://github.com/reduxjs/redux-devtools) to inspect the [navigation state](navigation-state.md) and actions, as well as perform time travel debugging by using the [`devtools` package](devtools.md).
diff --git a/versioned_docs/version-7.x/route-object.md b/versioned_docs/version-7.x/route-object.md
index 31c8d79ecc0..346af1b4ed1 100755
--- a/versioned_docs/version-7.x/route-object.md
+++ b/versioned_docs/version-7.x/route-object.md
@@ -4,6 +4,9 @@ title: Route object reference
sidebar_label: Route object
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Each `screen` component in your app is provided with the `route` object as a prop automatically. The prop contains various information regarding current route (place in navigation hierarchy component lives).
- `route`
@@ -12,9 +15,51 @@ Each `screen` component in your app is provided with the `route` object as a pro
- `path` - An optional string containing the path that opened the screen, exists when the screen was opened via a deep link.
- `params` - An optional object containing params which is defined while navigating e.g. `navigate('Twitter', { user: 'Dan Abramov' })`.
-
+
+
+
+```js name="Route prop" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator({
+ screens: {
+ Profile: ProfileScreen,
+ },
+});
+
+// codeblock-focus-start
+function ProfileScreen({ route }) {
+ return (
+
+ This is the profile screen of the app
+ {route.name}
+
+ );
+}
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Route prop" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
-```js
+const Stack = createNativeStackNavigator();
+
+// codeblock-focus-start
function ProfileScreen({ route }) {
return (
@@ -23,4 +68,18 @@ function ProfileScreen({ route }) {
);
}
+// codeblock-focus-end
+
+export default function App() {
+ return (
+
+
+
+
+
+ );
+}
```
+
+
+
diff --git a/versioned_docs/version-7.x/screen-options-resolution.md b/versioned_docs/version-7.x/screen-options-resolution.md
index 69eb1246043..1a97af4543a 100755
--- a/versioned_docs/version-7.x/screen-options-resolution.md
+++ b/versioned_docs/version-7.x/screen-options-resolution.md
@@ -1,22 +1,96 @@
---
id: screen-options-resolution
title: Screen options with nested navigators
-sidebar_label: Screen options with nested navigators
+sidebar_label: Options with nested navigators
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
In this document we'll explain how [screen options](screen-options.md) work when there are multiple navigators. It's important to understand this so that you put your `options` in the correct place and can properly configure your navigators. If you put them in the wrong place, at best nothing will happen and at worst something confusing and unexpected will happen.
**You can only modify navigation options for a navigator from one of its screen components. This applies equally to navigators that are nested as screens.**
Let's take for example a tab navigator that contains a native stack in each tab. What happens if we set the `options` on a screen inside of the stack?
-
+
+
-```js
-const Tab = createTabNavigator();
+```js name="Tabs with native stack" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function A() {
+ return ;
+}
+
+function B() {
+ return ;
+}
+
+// codeblock-focus-start
+const HomeStackScreen = createNativeStackNavigator({
+ screens: {
+ A: {
+ screen: A,
+ options: {
+ tabBarLabel: 'Home',
+ },
+ },
+ },
+});
+
+const SettingsStackScreen = createNativeStackNavigator({
+ screens: {
+ B: {
+ screen: B,
+ options: {
+ tabBarLabel: 'Settings!',
+ },
+ },
+ },
+});
+
+const Tab = createBottomTabNavigator({
+ screens: {
+ Home: HomeStackScreen,
+ Settings: SettingsStackScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Tabs with native stack" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Tab = createBottomTabNavigator();
const HomeStack = createNativeStackNavigator();
const SettingsStack = createNativeStackNavigator();
+function A() {
+ return ;
+}
+
+function B() {
+ return ;
+}
+// codeblock-focus-start
function HomeStackScreen() {
return (
@@ -51,13 +125,109 @@ export default function App() {
);
}
+// codeblock-focus-end
```
+
+
+
As we mentioned earlier, you can only modify navigation options for a navigator from one of its screen components. `A` and `B` above are screen components in `HomeStack` and `SettingsStack` respectively, not in the tab navigator. So the result will be that the `tabBarLabel` property is not applied to the tab navigator. We can fix this though!
-
+
+
-```js
+```js name="Tabs with native stack" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function A() {
+ return ;
+}
+
+function B() {
+ return ;
+}
+
+const HomeStackScreen = createNativeStackNavigator({
+ screens: {
+ A: A,
+ },
+});
+
+const SettingsStackScreen = createNativeStackNavigator({
+ screens: {
+ B: B,
+ },
+});
+
+// codeblock-focus-start
+const Tab = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeStackScreen,
+ options: {
+ tabBarLabel: 'Home!',
+ },
+ },
+ Settings: {
+ screen: SettingsStackScreen,
+ options: {
+ tabBarLabel: 'Settings!',
+ },
+ },
+ },
+});
+// codeblock-focus-start
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Tabs with native stack" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Tab = createBottomTabNavigator();
+const HomeStack = createNativeStackNavigator();
+const SettingsStack = createNativeStackNavigator();
+
+function A() {
+ return ;
+}
+
+function B() {
+ return ;
+}
+
+function HomeStackScreen() {
+ return (
+
+
+
+ );
+}
+
+function SettingsStackScreen() {
+ return (
+
+
+
+ );
+}
+
+// codeblock-focus-start
export default function App() {
return (
@@ -76,17 +246,116 @@ export default function App() {
);
}
+// codeblock-focus-end
```
+
+
+
When we set the `options` directly on `Screen` components containing the `HomeStack` and `SettingsStack` component, it allows us to control the options for its parent navigator when its used as a screen component. In this case, the options on our stack components configure the label in the tab navigator that renders the stacks.
## Setting parent screen options based on child navigator's state
Imagine the following configuration:
-
+
+
-```js
+```js name="Parent options from a child" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+function FeedScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function ProfileScreen() {
+ return ;
+}
+
+function AccountScreen() {
+ return ;
+}
+
+function SettingsScreen() {
+ return ;
+}
+
+// codeblock-focus-start
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Feed: FeedScreen,
+ Profile: ProfileScreen,
+ Account: AccountScreen,
+ },
+});
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeTabs,
+ Settings: SettingsScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Parent options from a child" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+function FeedScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function ProfileScreen() {
+ return ;
+}
+
+function AccountScreen() {
+ return ;
+}
+
+function SettingsScreen() {
+ return ;
+}
+
+// codeblock-focus-start
const Tab = createBottomTabNavigator();
function HomeTabs() {
@@ -111,8 +380,13 @@ export default function App() {
);
}
+
+// codeblock-focus-end
```
+
+
+
If we were to set the `headerTitle` with `options` for the `FeedScreen`, this would not work. This is because `App` stack will only look at its immediate children for configuration: `HomeTabs` and `SettingsScreen`.
But we can determine the `headerTitle` option based on the [navigation state](navigation-state.md) of our tab navigator using the `getFocusedRouteNameFromRoute` helper. Let's create a function to get the title first:
@@ -139,18 +413,185 @@ function getHeaderTitle(route) {
Then we can use this function with the `options` prop on `Screen`:
-
+
+
-```js
- ({
- headerTitle: getHeaderTitle(route),
- })}
-/>
+```js name="Parent options from a child" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+function getHeaderTitle(route) {
+ // If the focused route is not found, we need to assume it's the initial screen
+ // This can happen during if there hasn't been any navigation inside the screen
+ // In our case, it's "Feed" as that's the first screen inside the navigator
+ const routeName = getFocusedRouteNameFromRoute(route) ?? 'Feed';
+
+ switch (routeName) {
+ case 'Feed':
+ return 'News feed';
+ case 'Profile':
+ return 'My profile';
+ case 'Account':
+ return 'My account';
+ }
+}
+
+function FeedScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function ProfileScreen() {
+ return ;
+}
+
+function AccountScreen() {
+ return ;
+}
+
+function SettingsScreen() {
+ return ;
+}
+const HomeTabs = createBottomTabNavigator({
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Feed: FeedScreen,
+ Profile: ProfileScreen,
+ Account: AccountScreen,
+ },
+});
+
+// codeblock-focus-start
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeTabs,
+ options: ({ route }) => ({
+ headerTitle: getHeaderTitle(route),
+ }),
+ },
+ Settings: SettingsScreen,
+ },
+});
+// codeblock-focus-end
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
```
+
+
+
+
+```js name="Parent options from a child" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import {
+ NavigationContainer,
+ useNavigation,
+ getFocusedRouteNameFromRoute,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+function getHeaderTitle(route) {
+ // If the focused route is not found, we need to assume it's the initial screen
+ // This can happen during if there hasn't been any navigation inside the screen
+ // In our case, it's "Feed" as that's the first screen inside the navigator
+ const routeName = getFocusedRouteNameFromRoute(route) ?? 'Feed';
+
+ switch (routeName) {
+ case 'Feed':
+ return 'News feed';
+ case 'Profile':
+ return 'My profile';
+ case 'Account':
+ return 'My account';
+ }
+}
+
+function FeedScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function ProfileScreen() {
+ return ;
+}
+
+function AccountScreen() {
+ return ;
+}
+
+function SettingsScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+export default function App() {
+ return (
+
+
+ // codeblock-focus-start
+ ({
+ headerTitle: getHeaderTitle(route),
+ })}
+ />
+ // codeblock-focus-end
+
+
+
+ );
+}
+```
+
+
+
+
So what's happening here? With the `getFocusedRouteNameFromRoute` helper, we can get the currently active route name from this child navigator (in this case it's the tab navigator since that's what we're rendering) and setting an appropriate title for the header.
This approach can be used anytime you want to set options for a parent navigator based on a child navigator's state. Common use cases are:
@@ -163,11 +604,111 @@ In many cases, similar behavior can be achieved by reorganizing our navigators.
For example, for the above use case, instead of adding a tab navigator inside a stack navigator, we can add a stack navigator inside each of the tabs.
-
+
+
+
+```js name="Reorganized navigators" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+function FeedScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function ProfileScreen() {
+ return ;
+}
+
+function SettingsScreen() {
+ return ;
+}
+
+// codeblock-focus-start
+const FeedStackScreen = createNativeStackNavigator({
+ screens: {
+ Feed: FeedScreen,
+ /* other screens */
+ },
+});
+
+const ProfileStackScreen = createNativeStackNavigator({
+ screens: {
+ Profile: ProfileScreen,
+ /* other screens */
+ },
+});
+
+const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Feed: FeedStackScreen,
+ Profile: ProfileStackScreen,
+ },
+});
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeTabs,
+ Settings: SettingsScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Reorganized navigators" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+function FeedScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function ProfileScreen() {
+ return ;
+}
+
+function SettingsScreen() {
+ return ;
+}
-```js
const FeedStack = createNativeStackNavigator();
+// codeblock-focus-start
function FeedStackScreen() {
return (
@@ -211,8 +752,12 @@ export default function App() {
);
}
+// codeblock-focus-end
```
+
+
+
Additionally, this lets you push new screens to the feed and profile stacks without hiding the tab bar by adding more routes to those stacks.
If you want to push screens on top of the tab bar (i.e. that don't show the tab bar), then you can add them to the `App` stack instead of adding them into the screens inside the tab navigator.
diff --git a/versioned_docs/version-7.x/screen-options.md b/versioned_docs/version-7.x/screen-options.md
index 349ffe89c2a..1f95d0f3487 100644
--- a/versioned_docs/version-7.x/screen-options.md
+++ b/versioned_docs/version-7.x/screen-options.md
@@ -4,34 +4,168 @@ title: Options for screens
sidebar_label: Options for screens
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Each screen can configure various aspects about how it gets presented in the navigator that renders it by specifying certain options, for example, the header title in stack navigator, tab bar icon in bottom tab navigator etc. Different navigators support different set of options.
In the [configuring the header bar](headers.md) section of the fundamentals documentation we explain the basics of how this works. Also see the [screen options resolution guide](screen-options-resolution.md) to get an idea of how they work when there are multiple navigators.
+See [our docs](typescript.md#annotating-options-and-screenoptions) to learn more about how to use TypeScript with `screenOptions` and `options`.
+
There are 3 ways of specifying options for screens:
### `options` prop on `Screen`
You can pass a prop named `options` to the `Screen` component to configure a screen, where you can specify an object with different options for that screen:
-
+
+
+
+```js name="Screen title option" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import Button from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ navigation.navigate('Home')}>Go to Home
+
+ );
+}
+
+// codeblock-focus-start
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ title: 'Awesome app',
+ },
+ },
+ Profile: {
+ screen: ProfileScreen,
+ options: {
+ title: 'My profile',
+ },
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Screen title option" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import Button from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+ navigation.navigate('Home')}>Go to Home
+
+ );
+}
+
+export default function App() {
+ return (
+
+ // codeblock-focus-start
+
+
+
+
+ // codeblock-focus-end
+
+ );
+}
+```
+
+
+
+
+You can also pass a function to `options`. The function will receive the [`navigation` object](navigation-object.md) and the [`route` object](route-object.md) for that screen, as well as the [`theme` object](themes.md). This can be useful if you want to perform navigation in your options:
+
+
+
```js
-
-
-
-
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: ({ navigation }) => ({
+ title: 'Awesome app',
+ headerLeft: () => {
+ navigation.toggleDrawer()} />;
+ },
+ }),
+ },
+ },
+});
```
-You can also pass a function to `options`. The function will receive the [`navigation` object](navigation-object.md) and the [`route` object](route-object.md) for that screen. This can be useful if you want to perform navigation in your options:
+
+
```js
```
+
+
+
### `screenOptions` prop on `Group`
You can pass a prop named `screenOptions` to the `Group` component to configure screens inside the group, where you can specify an object with different options. The options specified in `screenOptions` apply to all of the screens in the group.
Example:
-
+
+
-```js
-
-
-
-
-
-
-
-
-
-
+```js name="Screen options for group" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+// codeblock-focus-start
+const Stack = createNativeStackNavigator({
+ groups: {
+ App: {
+ screenOptions: {
+ headerStyle: {
+ backgroundColor: '#FFB6C1',
+ },
+ },
+ screens: {
+ Home: ScreenWithButton('Home', 'Profile'),
+ Profile: ScreenWithButton('Profile', 'Settings'),
+ },
+ },
+ Modal: {
+ screenOptions: {
+ presentation: 'modal',
+ },
+ screens: {
+ Settings: ScreenWithButton('Settings', 'Share'),
+ Share: ScreenWithButton('Share'),
+ },
+ },
+ },
+});
+// codeblock-focus-end
+
+function ScreenWithButton(screenName, navigateTo) {
+ return function () {
+ const navigation = useNavigation();
+ return (
+
+ {screenName} Screen
+ {navigateTo && (
+ navigation.navigate(navigateTo)}>
+ Go to {navigateTo}
+
+ )}
+
+ );
+ };
+}
+const Navigation = createStaticNavigation(Stack);
+export default function App() {
+ return ;
+}
```
+
+
+
+```js name="Screen options for group" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Stack = createNativeStackNavigator();
+
+function ScreenWithButton(screenName, navigateTo) {
+ return function () {
+ const navigation = useNavigation();
+
+ return (
+
+ {screenName} Screen
+ {navigateTo && (
+ navigation.navigate(navigateTo)}>
+ Go to {navigateTo}
+
+ )}
+
+ );
+ };
+}
+
+const HomeScreen = ScreenWithButton('Home', 'Profile');
+const ProfileScreen = ScreenWithButton('Profile', 'Settings');
+const SettingsScreen = ScreenWithButton('Settings', 'Share');
+const ShareScreen = ScreenWithButton('Share');
+
+export default function App() {
+ return (
+
+ // codeblock-focus-start
+
+
+
+
+
+
+
+
+
+
+ // codeblock-focus-end
+
+ );
+}
+```
+
+
+
+
Similar to `options`, you can also pass a function to `screenOptions`. The function will receive the [`navigation` object](navigation-object.md) and the [`route` object](route-object.md) for each screen. This can be useful if you want to configure options for all the screens in one place based on the route:
+
+
+
+```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+ groups: {
+ Modal: {
+ screenOptions: {
+ presentation: 'modal',
+ headerLeft: () => ,
+ },
+ screens: {
+ Settings: Settings,
+ Share: Share,
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
@@ -87,12 +354,35 @@ Similar to `options`, you can also pass a function to `screenOptions`. The funct
```
+
+
+
### `screenOptions` prop on the navigator
-You can pass a prop named `screenOptions` to the navigator component, where you can specify an object with different options. The options specified in `screenOptions` apply to all of the screens in the navigator. So this is a good place to add specify options that you want to configure for the whole navigator.
+You can pass a prop named `screenOptions` to the navigator component, where you can specify an object with different options. The options specified in `screenOptions` apply to all of the screens in the navigator. So this is a good place to specify options that you want to configure for the whole navigator.
Example:
+
+
+
+```js
+const Stack = createNativeStackNavigator({
+ screenOptions: {
+ headerStyle: {
+ backgroundColor: 'papayawhip',
+ },
+ },
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+```
+
+
+
+
```js
```
+
+
+
Similar to `options`, you can also pass a function to `screenOptions`. The function will receive the [`navigation` object](navigation-object.md) and the [`route` object](route-object.md) for each screen. This can be useful if you want to configure options for all the screens in one place based on the route:
-
+
+
-```js
- ({
+```js name="Screen options for tab navigator" snack dependencies=@expo/vector-icons
+import * as React from 'react';
+import { View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { MaterialCommunityIcons } from '@expo/vector-icons';
+
+// codeblock-focus-start
+const Tab = createBottomTabNavigator({
+ screenOptions: ({ route }) => ({
tabBarIcon: ({ color, size }) => {
const icons = {
Home: 'home',
@@ -123,20 +424,81 @@ Similar to `options`, you can also pass a function to `screenOptions`. The funct
/>
);
},
- })}
->
-
-
-
+ }),
+ screens: {
+ Home: EmptyScreen,
+ Profile: EmptyScreen,
+ },
+});
+// codeblock-focus-end
+
+function EmptyScreen() {
+ return ;
+}
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Screen options for tab navigator" snack dependencies=@expo/vector-icons
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { MaterialCommunityIcons } from '@expo/vector-icons';
+
+const Tab = createBottomTabNavigator();
+
+function EmptyScreen() {
+ return ;
+}
+
+export default function App() {
+ return (
+
+ // codeblock-focus-start
+ ({
+ tabBarIcon: ({ color, size }) => {
+ const icons = {
+ Home: 'home',
+ Profile: 'account',
+ };
+
+ return (
+
+ );
+ },
+ })}
+ >
+
+
+
+ // codeblock-focus-end
+
+ );
+}
```
+
+
+
### `navigation.setOptions` method
The `navigation` object has a `setOptions` method that lets you update the options for a screen from within a component. See [navigation object's docs](navigation-object.md#setoptions) for more details.
```js
- navigation.setOptions({ title: 'Updated!' })}
-/>
+ navigation.setOptions({ title: 'Updated!' })}>
+ Update options
+
```
diff --git a/versioned_docs/version-7.x/screen-tracking.md b/versioned_docs/version-7.x/screen-tracking.md
index 17edf38f7b6..87786b0bfe4 100644
--- a/versioned_docs/version-7.x/screen-tracking.md
+++ b/versioned_docs/version-7.x/screen-tracking.md
@@ -1,9 +1,12 @@
---
id: screen-tracking
title: Screen tracking for analytics
-sidebar_label: Screen tracking for analytics
+sidebar_label: Screen tracking
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
To track the currently active screen, we need to:
1. Add a callback to get notified of state changes
@@ -15,42 +18,172 @@ To get notified of state changes, we can use the `onStateChange` prop on `Naviga
This example shows how the approach can be adapted to any mobile analytics SDK.
-
+
+
-```js
+```js name="Screen tracking for analytics" snack
+import * as React from 'react';
+import { View } from 'react-native';
+// codeblock-focus-start
+import {
+ createStaticNavigation,
+ useNavigationContainerRef,
+ useNavigation,
+} from '@react-navigation/native';
+// codeblock-focus-end
+import { Button } from '@react-navigation/elements';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function Home() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function Settings() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Home')}>Go to Home
+
+ );
+}
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: Home,
+ Settings: Settings,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+// codeblock-focus-start
+
+export default function App() {
+ const navigationRef = useNavigationContainerRef();
+ const routeNameRef = React.useRef();
+
+ return (
+ {
+ routeNameRef.current = navigationRef.current.getCurrentRoute().name;
+ }}
+ onStateChange={async () => {
+ const previousRouteName = routeNameRef.current;
+ const currentRouteName = navigationRef.current.getCurrentRoute().name;
+ const trackScreenView = () => {
+ // Your implementation of analytics goes here!
+ };
+
+ if (previousRouteName !== currentRouteName) {
+ // Replace the line below to add the tracker from a mobile analytics SDK
+ await trackScreenView(currentRouteName);
+ }
+
+ // Save the current route name for later comparison
+ routeNameRef.current = currentRouteName;
+ }}
+ />
+ );
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Screen tracking for anylytics" snack
+import * as React from 'react';
+import { View } from 'react-native';
+// codeblock-focus-start
import {
NavigationContainer,
+ useNavigation,
useNavigationContainerRef,
} from '@react-navigation/native';
+// codeblock-focus-end
+import { Button } from '@react-navigation/elements';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function Home() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+
+ );
+}
+
+function Settings() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Home')}>Go to Home
+
+ );
+}
+
+const Stack = createStackNavigator();
-export default () => {
+// codeblock-focus-start
+
+export default function App() {
const navigationRef = useNavigationContainerRef();
- const routeNameRef = useRef();
+ const routeNameRef = React.useRef();
return (
{
- routeNameRef.current = navigationRef.getCurrentRoute().name;
+ routeNameRef.current = navigationRef.current.getCurrentRoute().name;
}}
onStateChange={async () => {
const previousRouteName = routeNameRef.current;
- const currentRouteName = navigationRef.getCurrentRoute().name;
+ const currentRouteName = navigationRef.current.getCurrentRoute().name;
const trackScreenView = () => {
// Your implementation of analytics goes here!
};
if (previousRouteName !== currentRouteName) {
- // Save the current route name for later comparison
- routeNameRef.current = currentRouteName;
-
// Replace the line below to add the tracker from a mobile analytics SDK
await trackScreenView(currentRouteName);
}
+
+ // Save the current route name for later comparison
+ routeNameRef.current = currentRouteName;
}}
>
{/* ... */}
+ // codeblock-focus-end
+
+
+
+
+ // codeblock-focus-start
);
-};
+}
+// codeblock-focus-end
```
+
+
+
+
+:::note
+
+If you are building a library that wants to provide screen tracking integration with React Navigation, you can accept a [`ref`](navigation-container.md#ref) to the navigation container and use the [`ready`](navigation-container.md#ready) and [`state`](navigation-container.md#state) events instead of `onReady` and `onStateChange` props to keep your logic self-contained.
+
+:::
diff --git a/versioned_docs/version-7.x/screen.md b/versioned_docs/version-7.x/screen.md
index e1e7d07f51c..354b1a00ba4 100644
--- a/versioned_docs/version-7.x/screen.md
+++ b/versioned_docs/version-7.x/screen.md
@@ -4,35 +4,86 @@ title: Screen
sidebar_label: Screen
---
-`Screen` components are used to configure various aspects of screens inside a navigator.
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
-A `Screen` is returned from a `createXNavigator` function:
+A screen represents routes in a navigator. A screen's configuration contains the component for the route, options, event listeners, etc.
+
+
+
+
+Screens can be defined under the `screens` key in the navigator configuration:
```js
-const Stack = createNativeStackNavigator(); // Stack contains Screen & Navigator properties
+const MyStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
```
-After creating the navigator, it can be used as children of the `Navigator` component:
+
+
+
+A `Screen` component is returned from a `createXNavigator` function. After creating the navigator, it can be used as children of the `Navigator` component:
```js
-
-
-
-
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+
+
+
+
+ );
+}
```
You need to provide at least a name and a component to render for each screen.
-## Props
+
+
+
+## Configuration
+
+### Name
-### `name`
+The name to use for the screen.
-The name to use for the screen. It accepts a string:
+
+
+
+The key in the `screens` object is used as the name:
```js
-
+const Stack = createNativeStackNavigator({
+ screens: {
+ // highlight-next-line
+ Profile: {
+ screen: ProfileScreen,
+ },
+ },
+});
```
+
+
+
+It can be passed in the `name` prop to the `Screen` component:
+
+```jsx
+
+```
+
+
+
+
This name is used to navigate to the screen:
```js
@@ -41,157 +92,348 @@ navigation.navigate('Profile');
It is also used for the `name` property in the [`route`](route-object.md).
-While it is supported, we recommend to avoid spaces or special characters in screen names and keep them simple.
+While it is supported, we recommend avoiding spaces or special characters in screen names and keeping them simple.
-### `options`
+### Options
-Options to configure how the screen gets presented in the navigator. It accepts either an object or a function returning an object:
+Options are used to configure how the screen gets presented in the navigator. It accepts either an object or a function returning an object:
+
+
+
```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-start
+ options: {
+ title: 'Awesome app',
+ },
+ // highlight-end
+ },
+ },
+});
+```
+
+
+
+
+```jsx
```
-When you pass a function, it'll receive the [`route`](route-object.md) and [`navigation`](navigation-object.md):
+
+
+
+When you pass a function, it'll receive the [`route`](route-object.md), [`navigation`](navigation-object.md) and [`theme`](themes.md) as arguments:
+
+
+
```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-start
+ options: ({ route, navigation, theme }) => ({
+ title: route.params.userId,
+ }),
+ // highlight-end
+ },
+ },
+});
+```
+
+
+
+
+```jsx
({
title: route.params.userId,
})}
+ // highlight-end
/>
```
+
+
+
See [Options for screens](screen-options.md) for more details and examples.
-### `initialParams`
+### Initial params
+
+Initial params are used as the default params for the screen. If a screen is used as `initialRouteName`, it'll contain the params from `initialParams`. If you navigate to a new screen, the params passed are shallow merged with the initial params.
-Initial params to use for the screen. If a screen is used as `initialRouteName`, it'll contain the params from `initialParams`. If you navigate to a new screen, the params passed are shallow merged with the initial params.
+
+
```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Details: {
+ screen: DetailsScreen,
+ // highlight-next-line
+ initialParams: { itemId: 42 },
+ },
+ },
+});
+```
+
+
+
+
+```jsx
```
-### `getId`
+
+
+
+### ID
+
+A screen can have an ID to identify it uniquely. This is useful when you want to ensure that the screen with the same ID doesn't appear multiple times in the stack.
-Callback to return an unique ID to use for the screen. It receives an object with the route params:
+This can be done by specifying the `getId` callback. It receives an object with the route params:
+
+
+
```js
+const Stack = createStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-next-line
+ getId: ({ params }) => params.userId,
+ },
+ },
+});
+```
+
+
+
+
+```jsx
params.userId}
/>
```
-By default, `navigate('ScreenName', params)` updates the current screen if the screen name matches, otherwise adds a new screen in a stack navigator. So if you're on `ScreenName` and navigate to `ScreenName` again, it won't add a new screen even if the params are different - it'll update the current screen with the new params instead:
+
+
-```js
-// Let's say you're on `Home` screen
-// Then you navigate to `Profile` screen with `userId: 1`
-navigation.navigate('Profile', { userId: 1 });
+In the above example, `params.userId` is used as an ID for the `Profile` screen with `getId`. This changes how the navigation works to ensure that the screen with the same ID appears only once in the stack.
-// Now the stack will have: `Home` -> `Profile` with `userId: 1`
+Let's say you have a stack with the history `Home > Profile (userId: bob) > Settings`, consider following scenarios:
-// Then you navigate to `Profile` screen again with `userId: 2`
-navigation.navigate('Profile', { userId: 2 });
+- You call `navigate(Profile, { userId: 'bob' })`:
+ The resulting screens will be `Home > Settings > Profile (userId: bob)` since the existing `Profile` screen matches the ID.
+- You call `navigate(Profile, { userId: 'alice' })`:
+ The resulting screens will be `Home > Profile (userId: bob) > Settings > Profile (userId: alice)` since it'll add a new `Profile` screen as no matching screen was found.
-// The stack will now have: `Home` -> `Profile` with `userId: 2`
-```
+If `getId` is specified in a tab or drawer navigator, the screen will remount if the ID changes.
-If you specify `getId` and it doesn't return `undefined`, the screen is identified by both the screen name and the returned ID. Which means that if you're on `ScreenName` and navigate to `ScreenName` again with different params - and return a different ID from the `getId` callback, it'll add a new screen to the stack:
+:::warning
-```js
-// Let's say you're on `Home` screen
-// Then you navigate to `Profile` screen with `userId: 1`
-navigation.navigate('Profile', { userId: 1 });
+If you're using [`@react-navigation/native-stack`](native-stack-navigator.md), it doesn't work correctly with the `getId` callback. So it's recommended to avoid using it in that case.
-// Now the stack will have: `Home` -> `Profile` with `userId: 1`
+:::
-// Then you navigate to `Profile` screen again with `userId: 2`
-navigation.navigate('Profile', { userId: 2 });
+### Component
-// The stack will now have: `Home` -> `Profile` with `userId: 1` -> `Profile` with `userId: 2`
-```
+Each screen must specify a component to render for that route.
-The `getId` callback can also be used to ensure that the screen with the same ID doesn't appear multiple times in the stack:
+
+
-```js
-// Let's say you have a stack with the screens: `Home` -> `Profile` with `userId: 1` -> `Settings`
-// Then you navigate to `Profile` screen with `userId: 1` again
-navigation.navigate('Profile', { userId: 1 });
+It can be passed under the `screen` property in the screen configuration:
-// Now the stack will have: `Home` -> `Profile` with `userId: 1`
+```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Profile: {
+ // highlight-next-line
+ screen: ProfileScreen,
+ },
+ },
+});
```
-In the above examples, `params.userId` is used as an ID, subsequent navigation to the screen with the same `userId` will navigate to the existing screen instead of adding a new one to the stack. If the navigation was with a different `userId`, then it'll add a new screen.
+
+
-If `getId` is specified in a tab or drawer navigator, the screen will remount if the ID changes.
+#### `component`
-### `component`
+It can be passed in the `component` prop to the `Screen` component:
-The React Component to render for the screen:
-
-```js
-
+```jsx
+
```
-### `getComponent`
+#### `getComponent`
-Callback to return the React Component to render for the screen:
+It's also possible to pass a function in the `getComponent` prop to lazily evaluate the component:
-```js
+```jsx
require('./ProfileScreen').default}
/>
```
You can use this approach instead of the `component` prop if you want the `ProfileScreen` module to be lazily evaluated when needed. This is especially useful when using [ram bundles](https://reactnative.dev/docs/ram-bundles-inline-requires) to improve initial load.
-### `children`
+#### `children`
-Render callback to return React Element to use for the screen:
+Another way is to pass a render callback to return React Element to use for the screen:
-```js
+```jsx
+ // highlight-next-line
{(props) => }
```
-You can use this approach instead of the `component` prop if you need to pass additional props. Though we recommend using [React context](https://reactjs.org/docs/context.html) for passing data instead.
+You can use this approach instead of the `component` prop if you need to pass additional props. Though we recommend using [React context](https://react.dev/reference/react/useContext) for passing data instead.
:::warning
-By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) or [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) for your screen components to avoid performance issues.
+By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use [`React.memo`](https://react.dev/reference/react/memo) or [`React.PureComponent`](https://react.dev/reference/react/PureComponent) for your screen components to avoid performance issues.
:::
-### `navigationKey`
+
+
+
+### Layout
-Optional key for this screen. This doesn't need to be unique. If the key changes, existing screens with this name will be removed (if used in a stack navigator) or reset (if used in a tab or drawer navigator).
+A layout is a wrapper around the screen. It makes it easier to provide things such as an error boundary and suspense fallback for a screen, or wrap the screen with additional UI.
-This can be useful when we have some screens which we want to be removed or reset when the condition changes:
+It takes a function that returns a React element:
+
+
+
```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-start
+ layout: ({ children }) => (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ ),
+ // highlight-end
+ },
+ },
+});
+```
+
+
+
+
+```jsx
+ (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ )}
+ // highlight-end
+/>
+```
+
+To specify a layout for all multiple screens, you can use `screenLayout` in a [group](group.md#screen-layout) or [navigator](navigator.md#screen-layout).
+
+
+
+
+### Navigation key
+
+A navigation key is an optional key for this screen. This doesn't need to be unique. If the key changes, existing screens with this name will be removed (if used in a stack navigator) or reset (if used in a tab or drawer navigator).
+
+This can be useful when we have some screens that we want to be removed or reset when the condition changes:
+
+
+
+
+```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Profile: {
+ screen: ProfileScreen,
+ // highlight-next-line
+ navigationKey: 'user',
+ },
+ },
+});
+```
+
+For the static API, we recommend using the [`groups`](group.md#navigation-key) instead of the `navigationKey` for each screen as you can dynamically add or remove groups with the [`if`](static-configuration.md#if) property.
+
+
+
+
+```jsx
```
-### `listeners`
+
+
+
+### Event listeners
-Event listeners to subscribe to. See [`listeners` prop on `Screen`](navigation-events.md#listeners-prop-on-screen) for more details.
+Event listeners can be used to subscribe to various events emitted for the screen. See [`listeners` prop on `Screen`](navigation-events.md#listeners-prop-on-screen) for more details.
diff --git a/versioned_docs/version-7.x/server-rendering.md b/versioned_docs/version-7.x/server-rendering.md
index 814a1ad0adb..4dddb2019b0 100644
--- a/versioned_docs/version-7.x/server-rendering.md
+++ b/versioned_docs/version-7.x/server-rendering.md
@@ -4,11 +4,20 @@ title: Server rendering
sidebar_label: Server rendering
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
This guide will cover how to server render your React Native app using React Native for Web and React Navigation. We'll cover the following cases:
1. Rendering the correct layout depending on the request URL
2. Setting appropriate page metadata based on the focused screen
+:::warning
+
+Server rendering support is currently limited. It's not possible to provide a seamless SSR experience due to a lack of APIs such as media queries. In addition, many third-party libraries often don't work well with server rendering.
+
+:::
+
## Pre-requisites
Before you follow the guide, make sure that your app already renders fine on server. To do that, you will need to ensure the following:
@@ -130,16 +139,59 @@ app.use(async (ctx) => {
});
```
-Make sure that you have specified a `title` option in your screens:
+Make sure that you have specified a `title` option for your screens:
+
+
+
```js
-
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ // highlight-next-line
+ title: 'My App',
+ },
+ },
+ Profile: {
+ screen: ProfileScreen,
+ options: ({ route }) => ({
+ // highlight-next-line
+ title: `${route.params.name}'s Profile`,
+ }),
+ },
+ },
+});
```
+
+
+
+```js
+
+
+ ({
+ // highlight-next-line
+ title: `${route.params.name}'s Profile`,
+ })}
+ />
+
+```
+
+
+
+
## Handling 404 or other status codes
When [rendering a screen for an invalid URL](configuring-links.md#handling-unmatched-routes-or-404), we should also return a `404` status code from the server.
diff --git a/versioned_docs/version-7.x/shared-element-transitions.md b/versioned_docs/version-7.x/shared-element-transitions.md
index be85cc4d22b..18d5fd917f0 100644
--- a/versioned_docs/version-7.x/shared-element-transitions.md
+++ b/versioned_docs/version-7.x/shared-element-transitions.md
@@ -1,18 +1,25 @@
-# Animating elements between screens
+---
+id: shared-element-transitions
+title: Animating elements between screens
+sidebar_label: Shared element transitions
+---
-This guide covers how to animate elements between screens. This feature is known as a [Shared Element Transition](https://docs.swmansion.com/react-native-reanimated/docs/api/sharedElementTransitions) and it's implemented in the [`@react-navigation/native-stack`](native-stack-navigator.md) with [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/).
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+This guide covers how to animate elements between screens. This feature is known as a [Shared Element Transition](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/) and it's implemented in the [`@react-navigation/native-stack`](native-stack-navigator.md) with [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/).
:::warning
As of writing this guide, Shared Element Transitions are considered an experimental feature not recommended for production use.
+Shared Element Transitions are currently only supported on **old React Native architecture** (Paper).
+
:::
-
-
-
-
-
+
+
+
## Pre-requisites
@@ -29,24 +36,101 @@ To create a shared transition:
2. Assign the same `sharedTransitionTag` to elements on different screens.
3. Navigate between screens. The transition will start automatically.
-```jsx
+
+
+
+```js name="Shared transition"
import * as React from 'react';
-import { View, Button, StyleSheet } from 'react-native';
-import { NavigationContainer } from '@react-navigation/native';
+import { View, StyleSheet } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+
+import Animated from 'react-native-reanimated';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('Details')}>
+ Go to Details
+
+
+
+ );
+}
+
+function DetailsScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.goBack()}>Go back
+
+
+ );
+}
+
+// highlight-start
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Details: DetailsScreen,
+ },
+});
+// highlight-end
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ alignItems: 'center',
+ },
+});
+```
+
+
+
+
+```js name="Shared transition"
+import * as React from 'react';
+import { View, StyleSheet } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
import Animated from 'react-native-reanimated';
// highlight-next-line
const Stack = createNativeStackNavigator();
-function HomeScreen({ navigation }) {
+function HomeScreen() {
+ const navigation = useNavigation();
+
return (
- navigation.navigate('Details')}
- />
+ navigation.navigate('Details')}>
+ Go to Details
+
- navigation.goBack()} />
+ navigation.goBack()}>Go back
+
+
`sharedTransitionTag` is a string that has to be unique in the context of a single screen, but has to match elements between screens. This prop allows Reanimated to identify and animate the elements, similarly to the [`key`](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) property, which tells React which element in the list is which.
## Customizing the transition
diff --git a/versioned_docs/version-7.x/stack-actions.md b/versioned_docs/version-7.x/stack-actions.md
index 230177f0dd7..faa9cdf4340 100755
--- a/versioned_docs/version-7.x/stack-actions.md
+++ b/versioned_docs/version-7.x/stack-actions.md
@@ -4,6 +4,9 @@ title: StackActions reference
sidebar_label: StackActions
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`StackActions` is an object containing methods for generating actions specific to stack-based navigators. Its methods expand upon the actions available in [`CommonActions`](navigation-actions.md).
The following actions are supported:
@@ -15,21 +18,164 @@ The `replace` action allows to replace a route in the [navigation state](navigat
- `name` - _string_ - A destination name of the route that has been registered somewhere.
- `params` - _object_ - Params to pass to the destination route.
-
+
+
+
+```js name="Stack actions replace" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ StackActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ return (
+
+ Home!
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ navigation.dispatch(StackActions.pop(1))}>
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ navigation.dispatch(StackActions.popToTop())}>
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
-```js
-import { StackActions } from '@react-navigation/native';
+const Navigation = createStaticNavigation(Stack);
-navigation.dispatch(
- StackActions.replace('Profile', {
- user: 'jane',
- })
-);
+export default function App() {
+ return ;
+}
```
-If you want to replace a particular route, you can add a `source` property referring to the route key and `target` property referring to the navigation state key:
+
+
+
+```js name="Stack actions replace" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ StackActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen({ navigation }) {
+ return (
+
+ Home!
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ // codeblock-focus-end
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ navigation, route }) {
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ navigation.dispatch(StackActions.pop(1))}>
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ navigation.dispatch(StackActions.popToTop())}>
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
-
+
+
+
+If you want to replace a particular route, you can add a `source` property referring to the route key and `target` property referring to the navigation state key:
```js
import { StackActions } from '@react-navigation/native';
@@ -52,42 +198,344 @@ The `push` action adds a route on top of the stack and navigates forward to it.
- `name` - _string_ - Name of the route to push onto the stack.
- `params` - _object_ - Screen params to pass to the destination route.
-
+
+
+
+```js name="Stack actions push" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ StackActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ // codeblock-focus-end
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ navigation.dispatch(StackActions.pop(1))}>
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ navigation.dispatch(StackActions.popToTop())}>
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
-```js
-import { StackActions } from '@react-navigation/native';
+const Navigation = createStaticNavigation(Stack);
-const pushAction = StackActions.push('Profile', { user: 'Wojtek' });
+export default function App() {
+ return ;
+}
+```
-navigation.dispatch(pushAction);
+
+
+
+```js name="Stack actions push" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ StackActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen({ navigation }) {
+ return (
+
+ Home!
+ {
+ // codeblock-focus-start
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ // codeblock-focus-end
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ navigation, route }) {
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ navigation.dispatch(StackActions.pop(1))}>
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ navigation.dispatch(StackActions.popToTop())}>
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
### pop
The `pop` action takes you back to a previous screen in the stack. It takes one optional argument (`count`), which allows you to specify how many screens to pop back by.
-
+
+
+
+```js name="Stack actions pop" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+ StackActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ return (
+
+ Home!
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(StackActions.pop(1));
+ // codeblock-focus-end
+ }}
+ >
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ navigation.dispatch(StackActions.popToTop())}>
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
-```js
-import { StackActions } from '@react-navigation/native';
+const Navigation = createStaticNavigation(Stack);
-const popAction = StackActions.pop(1);
+export default function App() {
+ return ;
+}
+```
-navigation.dispatch(popAction);
+
+
+
+```js name="Stack actions pop" snack
+import * as React from 'react';
+import { Button } from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ StackActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen({ navigation }) {
+ return (
+
+ Home!
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ navigation, route }) {
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ {
+ // codeblock-focus-start
+ navigation.dispatch(StackActions.pop(1));
+ // codeblock-focus-end
+ }}
+ >
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ navigation.dispatch(StackActions.popToTop())}>
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
### popTo
The `popTo` action takes you back to a previous screen in the stack by the name. It also allows you to pass params to the route.
-If a matching screen is not found in the stack, this will pop the current screen and add a new screen with the specified name and params. This behavior is useful when the screen was opened from a deep link etc. and a previous screen with the name may or may not already be in the stack.
+If a matching screen is not found in the stack, this will pop the current screen and add a new screen with the specified name and params - essentially behaving like a [`replace`](#replace). This ensures that the app doesn't break if a previous screen with the name did not exist - which can happen when the screen was opened from a deep link or push notification, or when used on the web etc.
The method accepts the following arguments:
- `name` - _string_ - Name of the route to navigate to.
- `params` - _object_ - Screen params to pass to the destination route.
-
-If a matching screen is not found in the stack, this will pop the current screen and add a new screen with the specified name and params. This behavior is useful when the screen was opened from a deep link and a previous screen with the name may or may not already be in the stack.
+- `options` - Options object containing the following properties:
+ - `merge` - _boolean_ - Whether params should be merged with the existing route params, or replace them (when navigating to an existing screen). Defaults to `false`.
```js
import { StackActions } from '@react-navigation/native';
@@ -101,10 +549,167 @@ navigation.dispatch(popToAction);
The `popToTop` action takes you back to the first screen in the stack, dismissing all the others. It's functionally identical to `StackActions.pop({n: currentIndex})`.
-
+
+
+
+```js name="Stack actions popToTop" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ StackActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ return (
+
+ Home!
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ route }) {
+ const navigation = useNavigation();
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ navigation.dispatch(StackActions.pop(1))}>
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(StackActions.popToTop());
+ // codeblock-focus-end
+ }}
+ >
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
-```js
-import { StackActions } from '@react-navigation/native';
+const Navigation = createStaticNavigation(Stack);
-navigation.dispatch(StackActions.popToTop());
+export default function App() {
+ return ;
+}
```
+
+
+
+
+```js name="Stack actions pop" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ StackActions,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+
+function HomeScreen({ navigation }) {
+ return (
+
+ Home!
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push Profile on the stack
+
+ {
+ navigation.dispatch(
+ StackActions.replace('Profile', { user: 'Wojtek' })
+ );
+ }}
+ >
+ Replace with Profile
+
+
+ );
+}
+
+function ProfileScreen({ navigation, route }) {
+ return (
+
+ Profile!
+ {route.params.user}'s profile
+ navigation.dispatch(StackActions.pop(1))}>
+ Pop one screen from stack
+
+ {
+ navigation.dispatch(StackActions.push('Profile', { user: 'Wojtek' }));
+ }}
+ >
+ Push same screen on the stack
+
+ {
+ // codeblock-focus-start
+ navigation.dispatch(StackActions.popToTop());
+ // codeblock-focus-end
+ }}
+ >
+ Pop to top
+
+
+ );
+}
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
diff --git a/versioned_docs/version-7.x/stack-navigator.md b/versioned_docs/version-7.x/stack-navigator.md
index 233fc99554c..a512c9122c8 100755
--- a/versioned_docs/version-7.x/stack-navigator.md
+++ b/versioned_docs/version-7.x/stack-navigator.md
@@ -8,11 +8,13 @@ Stack Navigator provides a way for your app to transition between screens where
By default the stack navigator is configured to have the familiar iOS and Android look & feel: new screens slide in from the right on iOS, use OS default animation on Android. But the [animations can be customized](#animation-related-options) to match your needs.
-
-
-
-
-
+
+
+
+
+
+
+
One thing to keep in mind is that while `@react-navigation/stack` is extremely customizable, it's implemented in JavaScript. While it runs animations and gestures using natively, the performance may not be as fast as a native implementation. This may not be an issue for a lot of apps, but if you're experiencing performance issues during navigation, consider using [`@react-navigation/native-stack`](native-stack-navigator.md) instead - which uses native navigation primitives.
@@ -21,52 +23,33 @@ One thing to keep in mind is that while `@react-navigation/stack` is extremely c
To use this navigator, ensure that you have [`@react-navigation/native` and its dependencies (follow this guide)](getting-started.md), then install [`@react-navigation/stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/stack):
```bash npm2yarn
-npm install @react-navigation/stack@next
+npm install @react-navigation/stack
```
-Then, you need to install and configure the libraries that are required by the stack navigator:
-
-1. First, install [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/).
-
- If you have a Expo managed project, in your project directory, run:
-
- ```bash
- npx expo install react-native-gesture-handler
- ```
-
- If you have a bare React Native project, in your project directory, run:
-
- ```bash npm2yarn
- npm install react-native-gesture-handler
- ```
-
-2. To finalize installation of `react-native-gesture-handler`, add the following at the **top** (make sure it's at the top and there's nothing else before it) of your entry file, such as `index.js` or `App.js`:
-
- ```js
- import 'react-native-gesture-handler';
- ```
-
- :::warning
+The navigator depends on [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) for gestures and optionally [`@react-native-masked-view/masked-view`](https://github.com/react-native-masked-view/masked-view) for [UIKit style animations for the header](#headerstyleinterpolator).
- If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
+
+
- :::
+If you have a Expo managed project, in your project directory, run:
-3. Optionally, you can also install [`@react-native-masked-view/masked-view`](https://github.com/react-native-masked-view/masked-view). This is needed if you want to use UIKit style animations for the header ([`HeaderStyleInterpolators.forUIKit`](#headerstyleinterpolators)).
+```bash
+npx expo install react-native-gesture-handler @react-native-masked-view/masked-view
+```
- If you have a Expo managed project, in your project directory, run:
+
+
- ```bash
- npx expo install @react-native-masked-view/masked-view
- ```
+If you have a bare React Native project, in your project directory, run:
- If you have a bare React Native project, in your project directory, run:
+```bash npm2yarn
+npm install react-native-gesture-handler @react-native-masked-view/masked-view
+```
- ```bash npm2yarn
- npm install @react-native-masked-view/masked-view
- ```
+
+
-4. If you're on a Mac and developing for iOS, you also need to install the pods (via [Cocoapods](https://cocoapods.org/)) to complete the linking.
+If you're on a Mac and developing for iOS, you also need to install [pods](https://cocoapods.org/) to complete the linking.
```bash
npx pod-install ios
@@ -79,10 +62,14 @@ To use this navigator, import it from `@react-navigation/stack`:
-```js name="Stack Navigator" snack version=7
+```js name="Stack Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
-import { createStaticNavigation, useNavigation } from '@react-navigation/native';
+import { Text, View } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createStackNavigator } from '@react-navigation/stack';
@@ -93,10 +80,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -128,10 +114,11 @@ export default function App() {
-```js name="Stack Navigator" snack version=7
+```js name="Stack Navigator" snack
import * as React from 'react';
-import { Text, View, Button } from 'react-native';
+import { Text, View } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { Button } from '@react-navigation/elements';
// codeblock-focus-start
import { createStackNavigator } from '@react-navigation/stack';
@@ -153,10 +140,9 @@ function HomeScreen() {
return (
Home Screen
- navigation.navigate('Profile')}
- />
+ navigation.navigate('Profile')}>
+ Go to Profile
+
);
}
@@ -185,19 +171,7 @@ export default function App() {
### Props
-The `Stack.Navigator` component accepts following props:
-
-#### `id`
-
-Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator.
-
-#### `initialRouteName`
-
-The name of the route to render on first load of the navigator.
-
-#### `screenOptions`
-
-Default options to use for the screens in the navigator.
+In addition to the [common props](navigator.md#configuration) shared by all navigators, the stack navigator accepts the following additional props:
#### `detachInactiveScreens`
@@ -205,13 +179,9 @@ Boolean used to indicate whether inactive screens should be detached from the vi
If you need to disable this optimization for specific screens (e.g. you want to screen to stay in view even when unfocused) [`detachPreviousScreen`](#detachpreviousscreen) option.
-#### `keyboardHandlingEnabled`
-
-If `false`, the keyboard will NOT automatically dismiss when navigating to a new screen from this screen. Defaults to `true`.
-
### Options
-The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Stack.navigator` or `options` prop of `Stack.Screen`.
+The following [options](screen-options.md) can be used to configure the screens in the navigator. These can be specified under `screenOptions` prop of `Stack.Navigator` or `options` prop of `Stack.Screen`.
#### `title`
@@ -254,10 +224,6 @@ This is shortcut option which configures several options to configure the style
See [Transparent modals](#transparent-modals) for more details on how to customize `transparentModal`.
-#### `animationEnabled`
-
-Whether transition animation should be enabled on the screen. If you set it to `false`, the screen won't animate when pushing or popping. Defaults to `true` on iOS and Android, `false` on Web.
-
#### `animationTypeForReplace`
The type of animation to use when this screen replaces another screen. It takes the following values:
@@ -312,6 +278,10 @@ Interpolated styles for various parts of the card. Refer the [Animations section
Interpolated styles for various parts of the header. Refer the [Animations section](#animations) for details.
+#### `keyboardHandlingEnabled`
+
+If `false`, the keyboard will NOT automatically dismiss when navigating to a new screen from this screen. Defaults to `true`.
+
#### `detachPreviousScreen`
Boolean used to indicate whether to detach the previous screen from the view hierarchy to save memory. Set it to `false` if you need the previous screen to be seen through the active screen. Only applicable if `detachInactiveScreens` isn't set to `false`.
@@ -323,13 +293,11 @@ This is automatically adjusted when using [`presentation`](#presentation) as `tr
Boolean indicating whether to prevent inactive screens from re-rendering. Defaults to `false`.
Defaults to `true` when `enableFreeze()` from `react-native-screens` package is run at the top of the application.
-Requires `react-native-screens` version >=3.16.0.
-
Only supported on iOS and Android.
### Header related options
-You can find the list of header related options [here](elements.md#header). These [options](screen-options.md) can be specified under `screenOptions` prop of `Stack.navigator` or `options` prop of `Stack.Screen`. You don't have to be using `@react-navigation/elements` directly to use these options, they are just documented in that page.
+You can find the list of header related options [here](elements.md#header). These [options](screen-options.md) can be specified under `screenOptions` prop of `Stack.Navigator` or `options` prop of `Stack.Screen`. You don't have to be using `@react-navigation/elements` directly to use these options, they are just documented in that page.
In addition to those, the following options are also supported in stack:
@@ -412,8 +380,8 @@ return (
Specifies how the header should be rendered:
-- `float` - Render a single header that stays at the top and animates as screens are changed. This is default on iOS.
-- `screen` - Each screen has a header attached to it and the header fades in and out together with the screen. This is default on other platforms.
+- `float` - The header is rendered above the screen and animates independently of the screen. This is default on iOS for non-modals.
+- `screen` - The header is rendered as part of the screen and animates together with the screen. This is default on other platforms.
#### `headerShown`
@@ -433,16 +401,24 @@ Function which returns a React Element to display custom image in header's back
#### `headerBackTitle`
-Title string used by the back button on iOS. Defaults to the previous scene's `headerTitle`.
-
-#### `headerBackTitleVisible`
-
-A reasonable default is supplied for whether the back button title should be visible or not, but if you want to override that you can use `true` or `false` in this option.
+Title string used by the back button on iOS. Defaults to the previous scene's title. Use `headerBackButtonDisplayMode` to customize the behavior.
#### `headerTruncatedBackTitle`
Title string used by the back button when `headerBackTitle` doesn't fit on the screen. `"Back"` by default.
+#### `headerBackButtonDisplayMode`
+
+How the back button displays icon and title.
+
+Supported values:
+
+- `default`: Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
+- `generic`: Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon).
+- `minimal`: Always displays only the icon without a title.
+
+Defaults to `default` on iOS, and `minimal` on Android.
+
#### `headerBackTitleStyle`
Style object for the back title.
@@ -579,6 +555,8 @@ Navigates back to a previous screen in the stack by popping screens after it. Th
- `name` - _string_ - Name of the route to navigate to.
- `params` - _object_ - Screen params to pass to the destination route.
+- `options` - Options object containing the following properties:
+ - `merge` - _boolean_ - Whether params should be merged with the existing route params, or replace them (when navigating to an existing screen). Defaults to `false`.
If a matching screen is not found in the stack, this will pop the current screen and add a new screen with the specified name and params.
@@ -594,53 +572,49 @@ Pops all of the screens in the stack except the first one and navigates to it.
navigation.popToTop();
```
-## Example
+### Hooks
-
+The stack navigator exports the following hooks:
-```js
-import { createStackNavigator } from '@react-navigation/stack';
+#### `useCardAnimation`
-const Stack = createStackNavigator();
+This hook returns values related to the screen's animation. It contains the following properties:
-function MyStack() {
- return (
-
-
-
-
-
- );
-}
-```
+- `current` - Values for the current screen:
+ - `progress` - Animated node representing the progress value of the current screen.
+- `next` - Values for the screen after this one in the stack. This can be `undefined` in case the screen animating is the last one.
+ - `progress` - Animated node representing the progress value of the next screen.
+- `closing` - Animated node representing whether the card is closing. `1` when closing, `0` if not.
+- `swiping` - Animated node representing whether the card is being swiped. `1` when swiping, `0` if not.
+- `inverted` - Animated node representing whether the card is inverted. `-1` when inverted, `1` if not.
+- `index` - The index of the card in the stack.
+- `layouts` - Layout measurements for various items we use for animation.
+ - `screen` - Layout of the whole screen. Contains `height` and `width` properties.
+- `insets` - Layout of the safe area insets. Contains `top`, `right`, `bottom` and `left` properties.
+
+See [Transparent modals](#transparent-modals) for an example of how to use this hook.
## Animations
+You can specify the `animation` option to customize the transition animation for screens being pushed or popped.
+
+Supported values for `animation` are:
+
+- `default` - Default animation based on the platform and OS version.
+- `fade` - Simple fade animation for dialogs.
+- `fade_from_bottom` - Standard Android-style fade-in from the bottom for Android Oreo.
+- `fade_from_right` - Standard Android-style fade-in from the right for Android 14.
+- `reveal_from_bottom` - Standard Android-style reveal from the bottom for Android Pie.
+- `scale_from_center` - Scale animation from the center.
+- `slide_from_right` - Standard iOS-style slide in from the right.
+- `slide_from_left` - Similar to `slide_from_right`, but the screen will slide in from the left.
+- `slide_from_bottom` - Slide animation from the bottom for modals and bottom sheets.
+- `none` - The screens are pushed or popped immediately without any animation.
+
+By default, Android and iOS use the `default` animation and other platforms use `none`.
+
+If you need more control over the animation, you can customize individual parts of the animation using the various animation-related options:
+
### Animation related options
Stack Navigator exposes various options to configure the transition animation when a screen is added or removed. These transition animations can be customized on a per-screen basis by specifying the options in the `options` prop for each screen.
@@ -826,7 +800,7 @@ Stack Navigator exposes various options to configure the transition animation wh
- `title` - Layout of the title element. Might be `undefined` when not rendering a title.
- `leftLabel` - Layout of the back button label. Might be `undefined` when not rendering a back button label.
- A config which just fades the elements looks like this:
+ A config that just fades the elements looks like this:
```js
const forFade = ({ current, next }) => {
@@ -1032,18 +1006,13 @@ If you want to further customize how the dialog animates, or want to close the s
Example:
```js
-import {
- Animated,
- View,
- Text,
- Pressable,
- Button,
- StyleSheet,
-} from 'react-native';
-import { useTheme } from '@react-navigation/native';
+import { Animated, View, Text, Pressable, StyleSheet } from 'react-native';
+import { useTheme, useNavigation } from '@react-navigation/native';
import { useCardAnimation } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
-function ModalScreen({ navigation }) {
+function ModalScreen() {
+ const navigation = useNavigation();
const { colors } = useTheme();
const { current } = useCardAnimation();
@@ -1092,11 +1061,12 @@ function ModalScreen({ navigation }) {
pantry ten times.
+ >
+ Okay
+
);
diff --git a/versioned_docs/version-7.x/state-persistence.md b/versioned_docs/version-7.x/state-persistence.md
index 8d6c230867b..1e9cc94e24f 100755
--- a/versioned_docs/version-7.x/state-persistence.md
+++ b/versioned_docs/version-7.x/state-persistence.md
@@ -4,6 +4,9 @@ title: State persistence
sidebar_label: State persistence
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
You might want to save the user's location in the app, so that they are immediately returned to the same location after the app is restarted.
This is especially valuable during development because it allows the developer to stay on the same screen when they refresh the app.
@@ -15,13 +18,215 @@ To be able to persist the [navigation state](navigation-state.md), we can use th
- `onStateChange` - This prop notifies us of any state changes. We can persist the state in this callback.
- `initialState` - This prop allows us to pass an initial state to use for [navigation state](navigation-state.md). We can pass the restored state in this prop.
-
+
+
-```js
+```js name="Persisting the navigation state" snack dependencies=@react-native-async-storage/async-storage
+import * as React from 'react';
+// codeblock-focus-start
+import { Platform, View, Linking } from 'react-native';
+import AsyncStorage from '@react-native-async-storage/async-storage';
+import {
+ useNavigation,
+ createStaticNavigation,
+} from '@react-navigation/native';
+// codeblock-focus-end
+import { Button } from '@react-navigation/elements';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+function A() {
+ return ;
+}
+
+function B() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('C')}>Go to C
+
+ );
+}
+
+function C() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('D')}>Go to D
+
+ );
+}
+
+function D() {
+ return ;
+}
+
+const HomeStackScreen = createNativeStackNavigator({
+ screens: {
+ A: A,
+ },
+});
+
+const SettingsStackScreen = createNativeStackNavigator({
+ screens: {
+ B: B,
+ C: C,
+ D: D,
+ },
+});
+
+const Tab = createBottomTabNavigator({
+ screens: {
+ Home: {
+ screen: HomeStackScreen,
+ options: {
+ headerShown: false,
+ tabBarLabel: 'Home!',
+ },
+ },
+ Settings: {
+ screen: SettingsStackScreen,
+ options: {
+ headerShown: false,
+ tabBarLabel: 'Settings!',
+ },
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(Tab);
+
+// codeblock-focus-start
+
+const PERSISTENCE_KEY = 'NAVIGATION_STATE_V1';
+
+export default function App() {
+ const [isReady, setIsReady] = React.useState(Platform.OS === 'web'); // Don't persist state on web since it's based on URL
+ const [initialState, setInitialState] = React.useState();
+
+ React.useEffect(() => {
+ const restoreState = async () => {
+ try {
+ const initialUrl = await Linking.getInitialURL();
+
+ if (Platform.OS !== 'web' && initialUrl == null) {
+ const savedState = await AsyncStorage.getItem(PERSISTENCE_KEY);
+ const state = savedState ? JSON.parse(savedState) : undefined;
+
+ if (state !== undefined) {
+ setInitialState(state);
+ }
+ }
+ } finally {
+ setIsReady(true);
+ }
+ };
+
+ if (!isReady) {
+ restoreState();
+ }
+ }, [isReady]);
+
+ if (!isReady) {
+ return null;
+ }
+
+ return (
+
+ AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
+ }
+ />
+ );
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Persisting the navigation state" snack dependencies=@react-native-async-storage/async-storage
import * as React from 'react';
-import { Linking, Platform } from 'react-native';
+// codeblock-focus-start
+import { Platform, View, Linking } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
-import { NavigationContainer } from '@react-navigation/native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+// codeblock-focus-end
+import { Button } from '@react-navigation/elements';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const Tab = createBottomTabNavigator();
+const HomeStack = createNativeStackNavigator();
+const SettingsStack = createNativeStackNavigator();
+
+function A() {
+ return ;
+}
+
+function B() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('C')}>Go to C
+
+ );
+}
+
+function C() {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.navigate('D')}>Go to D
+
+ );
+}
+
+function D() {
+ return ;
+}
+
+function HomeStackScreen() {
+ return (
+
+
+
+ );
+}
+
+function SettingsStackScreen() {
+ return (
+
+
+
+
+
+ );
+}
+
+function RootTabs() {
+ return (
+
+
+
+
+ );
+}
+
+// codeblock-focus-start
const PERSISTENCE_KEY = 'NAVIGATION_STATE_V1';
@@ -66,12 +271,22 @@ export default function App() {
AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
}
>
- {/* ... */}
+
);
}
+// codeblock-focus-end
```
+
+
+
+:::warning
+
+It is recommended to use an [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) in your app and clear the persisted state if an error occurs. This will ensure that the app doesn't get stuck in an error state if a screen crashes.
+
+:::
+
### Development Mode
This feature is particularly useful in development mode. You can enable it selectively using the following approach:
@@ -80,7 +295,7 @@ This feature is particularly useful in development mode. You can enable it selec
const [isReady, setIsReady] = React.useState(__DEV__ ? false : true);
```
-While it can be used for production as well, use it with caution as it can make the app unusable if the app is crashing on a particular screen - as the user will still be on the same screen after restarting.
+While it can be used for production as well, use it with caution as it can make the app unusable if the app is crashing on a particular screen - as the user will still be on the same screen after restarting. So if you are using it in production, make sure to clear the persisted state if an error occurs.
### Loading View
@@ -94,6 +309,6 @@ if (!isReady) {
## Warning: Serializable State
-Each param, route, and navigation state must be fully serializable for this feature to work. Typically, you would serialize the state as a JSON string. This means that your routes and params must contain no functions, class instances, or recursive data structures. React Navigation already [warns you during development](troubleshooting.md#i-get-the-warning-"non-serializable-values-were-found-in-the-navigation-state") if it encounters non-serializable data, so watch out for the warning if you plan to persist navigation state.
+Each param, route, and navigation state must be fully serializable for this feature to work. Typically, you would serialize the state as a JSON string. This means that your routes and params must contain no functions, class instances, or recursive data structures. React Navigation already [warns you during development](troubleshooting.md#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state) if it encounters non-serializable data, so watch out for the warning if you plan to persist navigation state.
-You can modify the initial state object before passing it to container, but note that if your `initialState` isn't a [valid navigation state](navigation-state.md#partial-state-objects), React Navigation may not be able to handle the situation gracefully.
+You can modify the initial state object before passing it to container, but note that if your `initialState` isn't a [valid navigation state](navigation-state.md#stale-state-objects), React Navigation may not be able to handle the situation gracefully in some scenarios.
diff --git a/versioned_docs/version-7.x/static-authentication.md b/versioned_docs/version-7.x/static-authentication.md
deleted file mode 100644
index acfbec55ad4..00000000000
--- a/versioned_docs/version-7.x/static-authentication.md
+++ /dev/null
@@ -1,306 +0,0 @@
----
-id: static-authentication
-title: Authentication flow with static API
-sidebar_label: Authentication flow
----
-
-Most apps require that a user authenticate in some way to have access to data associated with a user or other private content. Typically the flow will look like this:
-
-- The user opens the app.
-- The app loads some authentication state from encrypted persistent storage (for example, [`SecureStore`](https://docs.expo.io/versions/latest/sdk/securestore/)).
-- When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
-- When the user signs out, we clear the authentication state and send them back to authentication screens.
-
-:::note
-
-We say "authentication screens" because usually there is more than one. You may have a main screen with a username and password field, another for "forgot password", and another set for sign up.
-
-:::
-
-## What we need
-
-This is the behavior that we want from the authentication flow: when users sign in, we want to throw away the state of the authentication flow and unmount all of the screens related to authentication, and when we press the hardware back button we expect to not be able to go back to the authentication flow.
-
-## How it will work
-
-We can configure different screens to be available based on some condition. For example, if the user is signed in, we can define `Home`, `Profile`, `Settings` etc. If the user is not signed in, we can define `SignIn` and `SignUp` screens. To do this, we need a couple of things:
-
-1. Define two hooks: `useIsSignedIn` and `useIsSignedOut`, which return a boolean value indicating whether the user is signed in or not.
-2. Use the `useIsSignedIn` and `useIsSignedOut` along with the [`if`](static-api-reference.md#if) property to define the screens that are available based on the condition.
-
-This tells React Navigation to show specific screens based on the signed in status. When the signed in status changes, React Navigation will automatically show the appropriate screen.
-
-## Don't manually navigate when using `if` for conditional screens
-
-It's important to note that when using such a setup, you **don't manually navigate** to the `Home` screen by calling `navigation.navigate('Home')` or any other method. **React Navigation will automatically navigate to the correct screen** when `isSignedIn` changes - `Home` screen when `isSignedIn` becomes `true`, and to `SignIn` screen when `isSignedIn` becomes `false`. You'll get an error if you attempt to navigate manually.
-
-## Define the hooks
-
-To implement the `useIsSignedIn` and `useIsSignedOut` hooks, we can start by creating a context to store the authentication state. Let's call it `SignInContext`:
-
-```js
-import * as React from 'react';
-
-const SignInContext = React.createContext();
-```
-
-Then we can implement the `useIsSignedIn` and `useIsSignedOut` hooks as follows:
-
-```js
-function useIsSignedIn() {
- const isSignedIn = React.useContext(SignInContext);
- return isSignedIn;
-}
-
-function useIsSignedOut() {
- const isSignedIn = React.useContext(SignInContext);
- return !isSignedIn;
-}
-```
-
-We'll discuss how to expose the context value later.
-
-## Define our screens
-
-For our case, let's say we have 3 screens:
-
-- `SplashScreen` - This will show a splash or loading screen when we're restoring the token.
-- `SignIn` - This is the screen we show if the user isn't signed in already (we couldn't find a token).
-- `Home` - This is the screen we show if the user is already signed in.
-
-We'd have our navigation tree defined with these screens as follows:
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- Home: {
- if: useIsSignedIn,
- screen: HomeScreen,
- },
- SignIn: {
- if: useIsSignedOut,
- screen: SignInScreen,
- options: {
- title: 'Sign in',
- },
- },
- },
-});
-
-const Navigation = createStaticNavigation(RootStack);
-```
-
-Notice how we have only defined the `Home` and `SignIn` screens here, and not the `SplashScreen`. The `SplashScreen` should be rendered before we render any navigators so that we don't render incorrect screens before we know whether the user is signed in or not.
-
-When we use this in our component, it'd look something like this:
-
-```js
-if (state.isLoading) {
- // We haven't finished checking for the token yet
- return ;
-}
-
-const isSignedIn = state.userToken != null;
-
-return (
-
-
-
-);
-```
-
-In the above snippet, `isLoading` means that we're still checking if we have a token. This can usually be done by checking if we have a token in `SecureStore` and validating the token. After we get the token and if it's valid, we need to set the `userToken`. We also have another state called `isSignout` to have a different animation on sign out.
-
-Next, we're exposing the sign in status via the `SignInContext` so that it's available to the `useIsSignedIn` and `useIsSignedOut` hooks.
-
-In the above example, we're have one screen for each case. But you could also define multiple screens. For example, you probably want to define password reset, signup, etc screens as well when the user isn't signed in. Similarly for the screens accessible after sign in, you probably have more than one screen. We can use [`groups`](static-api-reference.md#groups) to define multiple screens:
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- // Common screens
- },
- groups: {
- SignedIn: {
- if: useIsSignedIn,
- screens: {
- Home: HomeScreen,
- Profile: ProfileScreen,
- },
- },
- SignedOut: {
- if: useIsSignedOut,
- screens: {
- SignIn: SignInScreen,
- SignUp: SignUpScreen,
- ResetPassword: ResetPasswordScreen,
- },
- },
- },
-});
-```
-
-:::tip
-
-If you have both your login-related screens and rest of the screens in Stack navigators, we recommend to use a single Stack navigator and place the conditional inside instead of using 2 different navigators. This makes it possible to have a proper transition animation during login/logout.
-
-:::
-
-## Implement the logic for restoring the token
-
-:::note
-
-The following is just an example of how you might implement the logic for authentication in your app. You don't need to follow it as is.
-
-:::
-
-From the previous snippet, we can see that we need 2 state variables:
-
-- `isLoading` - We set this to `true` when we're trying to check if we already have a token saved in `SecureStore`
-- `userToken` - The token for the user. If it's non-null, we assume the user is logged in, otherwise not.
-
-So we need to:
-
-- Add some logic for restoring token, sign in and sign out
-- Expose methods for sign in and sign out to other components
-
-We'll use `React.useReducer` and `React.useContext` in this guide. But if you're using a state management library such as Redux or Mobx, you can use them for this functionality instead. In fact, in bigger apps, a global state management library is more suitable for storing authentication tokens. You can adapt the same approach to your state management library.
-
-First we'll need to create a context for auth where we can expose necessary methods:
-
-```js
-import * as React from 'react';
-
-const AuthContext = React.createContext();
-```
-
-In our component, we will:
-
-- Store the token and loading state in `useReducer`
-- Persist it to `SecureStore` and read it from there on app launch
-- Expose the methods for sign in and sign out to child components using `AuthContext`
-
-So we'll have something like this:
-
-```js
-import * as React from 'react';
-import * as SecureStore from 'expo-secure-store';
-
-export default function App({ navigation }) {
- const [state, dispatch] = React.useReducer(
- (prevState, action) => {
- switch (action.type) {
- case 'RESTORE_TOKEN':
- return {
- ...prevState,
- userToken: action.token,
- isLoading: false,
- };
- case 'SIGN_IN':
- return {
- ...prevState,
- userToken: action.token,
- };
- case 'SIGN_OUT':
- return {
- ...prevState,
- userToken: null,
- };
- }
- },
- {
- isLoading: true,
- userToken: null,
- }
- );
-
- React.useEffect(() => {
- // Fetch the token from storage then navigate to our appropriate place
- const bootstrapAsync = async () => {
- let userToken;
-
- try {
- userToken = await SecureStore.getItemAsync('userToken');
- } catch (e) {
- // Restoring token failed
- }
-
- // After restoring token, we may need to validate it in production apps
- // ...
-
- // This will switch to the App screen or Auth screen and this loading
- // screen will be unmounted and thrown away.
- dispatch({ type: 'RESTORE_TOKEN', token: userToken });
- };
-
- bootstrapAsync();
- }, []);
-
- const authContext = React.useMemo(
- () => ({
- signIn: async (data) => {
- // In a production app, we need to send some data (usually username, password) to server and get a token
- // We will also need to handle errors if sign in failed
- // After getting token, we need to persist the token using `SecureStore`
- // In the example, we'll use a dummy token
-
- dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
- },
- signOut: () => dispatch({ type: 'SIGN_OUT' }),
- signUp: async (data) => {
- // In a production app, we need to send user data to server and get a token
- // We will also need to handle errors if sign up failed
- // After getting token, we need to persist the token using `SecureStore`
- // In the example, we'll use a dummy token
-
- dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
- },
- }),
- []
- );
-
- if (state.isLoading) {
- return ;
- }
-
- return (
-
-
-
-
-
- );
-}
-```
-
-## Fill in other components
-
-We won't talk about how to implement the text inputs and buttons for the authentication screen, that is outside of the scope of navigation. We'll just fill in some placeholder content.
-
-```js
-function SignInScreen() {
- const [username, setUsername] = React.useState('');
- const [password, setPassword] = React.useState('');
-
- const { signIn } = React.useContext(AuthContext);
-
- return (
-
-
-
- signIn({ username, password })} />
-
- );
-}
-```
-
-You can similarly fill in the other screens according to your requirements.
diff --git a/versioned_docs/version-7.x/static-api-reference.md b/versioned_docs/version-7.x/static-configuration.md
similarity index 58%
rename from versioned_docs/version-7.x/static-api-reference.md
rename to versioned_docs/version-7.x/static-configuration.md
index e297650eb8b..a272bef5a71 100644
--- a/versioned_docs/version-7.x/static-api-reference.md
+++ b/versioned_docs/version-7.x/static-configuration.md
@@ -1,7 +1,7 @@
---
-id: static-api-reference
-title: Static API Reference
-sidebar_label: API Reference
+id: static-configuration
+title: Static configuration
+sidebar_label: Static configuration
---
The bulk of the static configuration is done using the `createXNavigator` functions, e.g. [`createNativeStackNavigator`](native-stack-navigator.md), [`createBottomTabNavigator`](bottom-tab-navigator.md), [`createDrawerNavigator`](drawer-navigator.md) etc. We'll refer to these functions as `createXNavigator` in the rest of this guide.
@@ -10,7 +10,7 @@ The bulk of the static configuration is done using the `createXNavigator` functi
The `createXNavigator` functions take one argument, which is an object with the following properties:
-- Same props as the navigator component, e.g. `id`, `initialRouteName`, `screenOptions` etc. See the docs for each navigator for more details on the props they accept.
+- Same props as the navigator component, e.g. `id`, `initialRouteName`, `screenOptions` etc. See [Navigator](navigator.md) as well as the docs for each navigator for more details on the props they accept.
- `screens` - an object containing configuration for each screen in the navigator.
- `groups` - an optional object containing groups of screens (equivalent to [`Group`](group.md) in the dynamic API).
@@ -82,10 +82,11 @@ The `screens` object can contain key value pairs where the key is the name of th
### `groups`
-The `groups` object can contain key value pairs where the key is the name of the group and the value is the group configuration. The group configuration can contain the following properties:
+The `groups` object can contain key-value pairs where the key is the name of the group and the value is the group configuration.
+
+The configuration object for a screen accepts the [properties described in the Group page](group.md). In addition, the following properties are available when using static configuration:
- `if` - this can be used to conditionally render the group and works the same as the [`if` property in the screen configuration](#if).
-- `screenOptions` - default options for all screens under this group.
- `screens` - an object containing configuration for each screen in the group. The configuration is the same as the [`screens` object in the navigator configuration](#screens).
Example:
@@ -104,39 +105,21 @@ const RootStack = createNativeStackNavigator({
},
screens: {
// ...
- }
+ },
},
User: {
if: useIsUser,
screens: {
// ...
- }
- }
+ },
+ },
},
});
```
-The keys of the `groups` object (e.g. `Guest`, `User`) are used as the [`navigationKey`](group.md#navigationkey) for the group - this means if a screen is defined in 2 groups and the groups use the [`if`](#if) property, the screen will remount if the condition changes resulting in one group being removed and other group being used. You can use any string as the key.
-
### Screen configuration
-The configuration object for a screen can contain the following properties:
-
-#### `screen`
-
-The React component or navigator to render for the screen:
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- Home: {
- screen: HomeScreen,
- },
- },
-});
-```
-
-The screen components defined with the static configuration receive the [`route`](route-object.md) prop. Unlike the dynamic API, they don't get the `navigation` object as prop and it must be accessed via the [`useNavigation`](use-navigation.md) hook.
+The configuration object for a screen accepts the [properties described in the Screen page](screen.md). In addition, the following properties are available when using static configuration:
#### `linking`
@@ -167,7 +150,7 @@ const RootStack = createNativeStackNavigator({
The `linking` object supports the same configuration options described in [Configuring links](configuring-links.md) such as `parse`, `stringify` and `exact`.
-To make deep links work on native apps, you also need to [configure your app](deep-linking.md) and pass `prefixes` to the navigation component returned by [`createStaticNavigation`](static-api-reference.md#createstaticnavigation):
+To make deep links work on native apps, you also need to [configure your app](deep-linking.md) and pass `prefixes` to the navigation component returned by [`createStaticNavigation`](static-configuration.md#createstaticnavigation):
```js
const Navigation = createStaticNavigation(RootStack);
@@ -206,95 +189,7 @@ const RootStack = createNativeStackNavigator({
The above example will only render the `HomeScreen` if the user is logged in.
-For more details, see [Authentication flow with static API](static-authentication.md).
-
-#### `options`
-
-Options to configure how the screen gets presented in the navigator. It accepts either an object or a function returning an object:
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- Home: {
- screen: HomeScreen,
- options: {
- title: 'Awesome app',
- },
- },
- },
-});
-```
-
-When you pass a function, it'll receive the [`route`](route-object.md) and [`navigation`](navigation-object.md):
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- Profile: {
- screen: ProfileScreen,
- options: ({ route, navigation }) => ({
- title: route.params.userId,
- }),
- },
- },
-});
-```
-
-See [Options for screens](screen-options.md) for more details and examples.
-
-#### `initialParams`
-
-Initial params to use for the screen. If a screen is used as `initialRouteName`, it'll contain the params from `initialParams`. If you navigate to a new screen, the params passed are shallow merged with the initial params.
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- Details: {
- screen: DetailsScreen,
- initialParams: { itemId: 5 },
- },
- },
-});
-```
-
-#### `getId`
-
-Callback to return an unique ID to use for the screen. It receives an object with the route params:
-
-```js
-const RootStack = createNativeStackNavigator({
- screens: {
- Profile: {
- screen: ProfileScreen,
- getId: ({ params }) => params.userId,
- },
- },
-});
-```
-
-By default, calling `navigate('ScreenName', params)` identifies the screen by its name, and navigates to the existing screen instead of adding a new one. If you specify `getId` and it doesn't return `undefined`, the screen is identified by both the screen name and the returned ID.
-
-This is useful for preventing multiple instances of the same screen in the navigator, e.g. - when `params.userId` is used as an ID, subsequent navigation to the screen with the same `userId` will navigate to the existing screen instead of adding a new one to the stack. If the navigation was with a different `userId`, then it'll add a new screen.
-
-#### `listeners`
-
-Event listeners to subscribe to. It takes an object with the event names as keys and the listener callbacks as values:
-
-```js
-const BottomTab = createBottomTabNavigator({
- screens: {
- Chat: {
- screen: ChatScreen,
- listeners: {
- tabPress: (e) => {
- // Prevent default action
- e.preventDefault();
- },
- },
- },
- },
-});
-```
+For more details, see [Authentication flow](auth-flow.md?config=static).
## `createStaticNavigation`
@@ -308,21 +203,45 @@ function App() {
}
```
-This component is a wrapper around the `NavigationContainer` component and accepts the [same props and ref as the `NavigationContainer`](navigation-container.md) component. There's however one difference - the `linking` prop accepted by this component doesn't take a `config` property. Instead, the linking config is automatically inferred from the static config.
+This component is a wrapper around the `NavigationContainer` component and accepts the [same props and ref as the `NavigationContainer`](navigation-container.md) component. It is intended to be rendered once at the root of your app similar to how you'd use `NavigationContainer` component.
+
+### Differences in the `linking` prop
+
+Similar to `NavigationContainer`, the component returned by `createStaticNavigation` also accepts a [`linking`](navigation-container.md#linking) prop. However, there are some key differences:
+
+1. It's not possible to pass a full `config` object to the `linking` prop. It can only accept [`path`](configuring-links.md#apps-under-subpaths) and an [`initialRouteName` for the root navigator](configuring-links.md#rendering-an-initial-route).
+2. The linking config is collected from the [`linking`](#linking) properties specified in the screen configuration.
+3. It's possible to pass `enabled: 'auto'` to automatically generate paths for all leaf screens:
+
+ ```js
+ const Navigation = createStaticNavigation(RootStack);
+
+ const linking = {
+ enabled: 'auto',
+ prefixes: ['https://example.com', 'example://'],
+ };
+
+ function App() {
+ return ;
+ }
+ ```
-This is intended to be rendered once at the root of your app similar to how you'd use `NavigationContainer` component.
+ See [How does automatic path generation work](configuring-links.md#how-does-automatic-path-generation-work) for more details.
## `createComponentForStaticNavigation`
The `createComponentForStaticNavigation` function takes the static config returned by `createXNavigator` functions and returns a React component to render. The second argument is a name for the component that'd be used in React DevTools:
```js
-const RootStackNavigator = createComponentForStaticNavigation(RootStack, 'RootNavigator');
+const RootStackNavigator = createComponentForStaticNavigation(
+ RootStack,
+ 'RootNavigator'
+);
```
The returned component doesn't take any props. All of the configuration is inferred from the static config. It's essentially the same as defining a component using the dynamic API.
-This looks similar to `createStaticNavigation` however they are very different. When using static configuration, you'd never use this function directly. The only time you'd use this is if you're migrating away from static configuration and want to reuse existing code you wrote instead of rewriting it to the dynamic API. See [Combining static and dynamic APIs](static-combine-with-dynamic.md) for more details.
+This looks similar to `createStaticNavigation` however they are very different. When using static configuration, you'd never use this function directly. The only time you'd use this is if you're migrating away from static configuration and want to reuse existing code you wrote instead of rewriting it to the dynamic API. See [Combining static and dynamic APIs](combine-static-with-dynamic.md) for more details.
## `createPathConfigForStaticNavigation`
@@ -338,4 +257,4 @@ const config = {
};
```
-Similar to `createComponentForStaticNavigation`, this is intended to be used when migrating away from static configuration. See [Combining static and dynamic APIs](static-combine-with-dynamic.md) for more details.
+Similar to `createComponentForStaticNavigation`, this is intended to be used when migrating away from static configuration. See [Combining static and dynamic APIs](combine-static-with-dynamic.md) for more details.
diff --git a/versioned_docs/version-7.x/static-typescript.md b/versioned_docs/version-7.x/static-typescript.md
deleted file mode 100644
index ed11306a86b..00000000000
--- a/versioned_docs/version-7.x/static-typescript.md
+++ /dev/null
@@ -1,117 +0,0 @@
----
-id: static-typescript
-title: Configuring TypeScript with static API
-sidebar_label: Configuring TypeScript
----
-
-There are 2 steps to configure TypeScript with the static API:
-
-1. Each screen component needs to specify the type of the `route.params` prop that it accepts. The `StaticScreenProps` type makes it simpler:
-
-```ts
-import type { StaticScreenProps } from '@react-navigation/native';
-
-type Props = StaticScreenProps<{
- username: string;
-}>;
-
-function ProfileScreen({ route }: Props) {
- // ...
-}
-```
-
-1. Generate the `ParamList` type for the root navigator and specify it as the default type for the `RootParamList` type:
-
-```ts
-import type { StaticParamList } from '@react-navigation/native';
-
-const HomeTabs = createBottomTabNavigator({
- screens: {
- Feed: FeedScreen,
- Profile: ProfileScreen,
- },
-});
-
-const RootStack = createNativeStackNavigator({
- screens: {
- Home: HomeTabs,
- },
-});
-
-type RootStackParamList = StaticParamList;
-
-declare global {
- namespace ReactNavigation {
- interface RootParamList extends RootStackParamList {}
- }
-}
-```
-
-This is needed to type-check the `useNavigation` hook.
-
-## Navigator specific types
-
-Generally we recommend using the default types for the `useNavigation` prop to access the navigation object in a navigator agnostic manner. However, if you need to use navigator specific APIs, you need to manually annotate `useNavigation`:
-
-```ts
-type BottomTabParamList = StaticParamList;
-type ProfileScreenNavigationProp = BottomTabNavigationProp<
- BottomTabParamList,
- 'Profile'
->;
-
-// ...
-
-const navigation = useNavigation();
-```
-
-This follows the same principle as the types described in [Type checking with TypeScript](typescript.md).
-
-Note that annotating `useNavigation` this way not type-safe since we can't guarantee that the type you provided matches the type of the navigator.
-
-## Nesting navigator using dynamic API
-
-Consider the following example:
-
-```js
-const Tab = createBottomTabNavigator();
-
-function HomeTabs() {
- return (
-
-
-
-
- );
-}
-
-const RootStack = createStackNavigator({
- Home: HomeTabs,
-});
-```
-
-Here, the `HomeTabs` component is defined using the dynamic API. This means that when we create the param list for the root navigator with `StaticParamList`, it won't know about the screens defined in the nested navigator. To fix this, we'd need to specify the param list for the nested navigator explicitly.
-
-This can be done by using the type of the `route` prop that the screen component receives:
-
-```ts
-type HomeTabsParamList = {
- Feed: undefined;
- Profile: undefined;
-};
-
-type HomeTabsProps = StaticScreenProps<
- NavigatorScreenParams
->;
-
-function HomeTabs(_: HomeTabsProps) {
- return (
-
-
-
-
- );
-}
-```
-
-Now, when using `StaticParamList`, it will include the screens defined in the nested navigator.
diff --git a/versioned_docs/version-7.x/status-bar.md b/versioned_docs/version-7.x/status-bar.md
index c24aaf19ffd..9b97b4820db 100755
--- a/versioned_docs/version-7.x/status-bar.md
+++ b/versioned_docs/version-7.x/status-bar.md
@@ -1,28 +1,126 @@
---
id: status-bar
title: Different status bar configuration based on route
-sidebar_label: Different status bar configuration based on route
+sidebar_label: Status bar configuration
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
If you don't have a navigation header, or your navigation header changes color based on the route, you'll want to ensure that the correct color is used for the content.
## Stack
This is a simple task when using a stack. You can render the `StatusBar` component, which is exposed by React Native, and set your config.
-
+
+
-```js
+```js name="Different status bar" snack
+import * as React from 'react';
+import { View, Text, StatusBar, StyleSheet } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
+
+function Screen1() {
+ const navigation = useNavigation();
+ const insets = useSafeAreaInsets();
+
+ return (
+
+ // highlight-start
+
+ // highlight-end
+ Light Screen
+ navigation.navigate('Screen2')}>
+ Next screen
+
+
+ );
+}
+
+function Screen2() {
+ const navigation = useNavigation();
+ const insets = useSafeAreaInsets();
+
+ return (
+
+ // highlight-start
+
+ // highlight-end
+ Dark Screen
+ navigation.navigate('Screen1')}>
+ Next screen
+
+
+ );
+}
+
+const RootStack = createNativeStackNavigator({
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Screen1: Screen1,
+ Screen2: Screen2,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+
+const styles = StyleSheet.create({
+ container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
+});
+```
+
+
+
+
+
+```js name="Different status bar" snack
import * as React from 'react';
-import { View, Text, StatusBar, Button, StyleSheet } from 'react-native';
-import { NavigationContainer } from '@react-navigation/native';
+import { View, Text, StatusBar, StyleSheet } from 'react-native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
import {
SafeAreaProvider,
useSafeAreaInsets,
} from 'react-native-safe-area-context';
-function Screen1({ navigation }) {
+function Screen1() {
+ const navigation = useNavigation();
const insets = useSafeAreaInsets();
return (
@@ -38,18 +136,19 @@ function Screen1({ navigation }) {
},
]}
>
+ // highlight-start
+ // highlight-end
Light Screen
- navigation.navigate('Screen2')}
- color="#fff"
- />
+ navigation.navigate('Screen2')}>
+ Next screen
+
);
}
-function Screen2({ navigation }) {
+function Screen2() {
+ const navigation = useNavigation();
const insets = useSafeAreaInsets();
return (
@@ -65,12 +164,13 @@ function Screen2({ navigation }) {
},
]}
>
+ // highlight-start
+ // highlight-end
Dark Screen
- navigation.navigate('Screen1')}
- />
+ navigation.navigate('Screen1')}>
+ Next screen
+
);
}
@@ -99,7 +199,16 @@ const styles = StyleSheet.create({
});
```
-
+
+
+
+
+
+
+
+
+
+
## Tabs and Drawer
@@ -121,10 +230,30 @@ function FocusAwareStatusBar(props) {
Now, our screens (both `Screen1.js` and `Screen2.js`) will use the `FocusAwareStatusBar` component instead of the `StatusBar` component from React Native:
-
+
+
+
+```js name="Different status bar based on tabs" snack
+import * as React from 'react';
+import { View, Text, StatusBar, StyleSheet } from 'react-native';
+import { useIsFocused } from '@react-navigation/native';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
+
+function FocusAwareStatusBar(props) {
+ const isFocused = useIsFocused();
-```jsx
-function Screen1({ navigation }) {
+ return isFocused ? : null;
+}
+
+// codeblock-focus-start
+function Screen1() {
+ const navigation = useNavigation();
const insets = useSafeAreaInsets();
return (
@@ -142,16 +271,15 @@ function Screen1({ navigation }) {
>
Light Screen
- navigation.navigate('Screen2')}
- color="#fff"
- />
+ navigation.navigate('Screen2')}>
+ Next screen
+
);
}
-function Screen2({ navigation }) {
+function Screen2() {
+ const navigation = useNavigation();
const insets = useSafeAreaInsets();
return (
@@ -169,17 +297,157 @@ function Screen2({ navigation }) {
>
Dark Screen
- navigation.navigate('Screen1')}
- />
+ navigation.navigate('Screen1')}>
+ Next screen
+
);
}
+// codeblock-focus-end
+
+const RootStack = createNativeStackNavigator({
+ screenOptions: {
+ headerShown: false,
+ },
+ screens: {
+ Screen1: Screen1,
+ Screen2: Screen2,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
```
+
+
+
+```js name="Different status bar based on tabs" snack
+import * as React from 'react';
+import { View, Text, StatusBar, StyleSheet } from 'react-native';
+import { useIsFocused } from '@react-navigation/native';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { Button } from '@react-navigation/elements';
+import {
+ SafeAreaProvider,
+ useSafeAreaInsets,
+} from 'react-native-safe-area-context';
+
+function FocusAwareStatusBar(props) {
+ const isFocused = useIsFocused();
+
+ return isFocused ? : null;
+}
+
+// codeblock-focus-start
+function Screen1() {
+ const navigation = useNavigation();
+ const insets = useSafeAreaInsets();
+
+ return (
+
+
+ Light Screen
+ navigation.navigate('Screen2')}>
+ Next screen
+
+
+ );
+}
+
+function Screen2() {
+ const navigation = useNavigation();
+ const insets = useSafeAreaInsets();
+
+ return (
+
+
+ Dark Screen
+ navigation.navigate('Screen1')}>
+ Next screen
+
+
+ );
+}
+// codeblock-focus-end
+
+const Stack = createNativeStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+```
+
+
+
+
Although not necessary, you can use the `FocusAwareStatusBar` component in the screens of the native stack navigator as well.
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
diff --git a/versioned_docs/version-7.x/tab-actions.md b/versioned_docs/version-7.x/tab-actions.md
index ab2d179a3e2..3e8fd06add7 100755
--- a/versioned_docs/version-7.x/tab-actions.md
+++ b/versioned_docs/version-7.x/tab-actions.md
@@ -4,6 +4,9 @@ title: TabActions reference
sidebar_label: TabActions
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`TabActions` is an object containing methods for generating actions specific to tab-based navigators. Its methods expand upon the actions available in [`CommonActions`](navigation-actions.md).
The following actions are supported:
@@ -15,12 +18,123 @@ The `jumpTo` action can be used to jump to an existing route in the tab navigato
- `name` - _string_ - Name of the route to jump to.
- `params` - _object_ - Screen params to pass to the destination route.
-
+
+
+
+```js name="Tab Actions - jumpTo" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+ TabActions,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
+ // highlight-next-line
+ const jumpToAction = TabActions.jumpTo('Profile', { user: 'Satya' });
+
+ return (
+
+ Home!
+ {
+ // highlight-next-line
+ navigation.dispatch(jumpToAction);
+ }}
+ >
+ Jump to Profile
+
+
+ );
+}
+// codeblock-focus-end
+
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+const Tab = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Tab);
-```js
-import { TabActions } from '@react-navigation/native';
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="Tab Actions - jumpTo" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ NavigationContainer,
+ TabActions,
+ useNavigation,
+} from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+// codeblock-focus-start
+function HomeScreen() {
+ const navigation = useNavigation();
+ // highlight-next-line
+ const jumpToAction = TabActions.jumpTo('Profile', { user: 'Satya' });
-const jumpToAction = TabActions.jumpTo('Profile', { user: 'Satya' });
+ return (
+
+ Home!
+ {
+ // highlight-next-line
+ navigation.dispatch(jumpToAction);
+ }}
+ >
+ Jump to Profile
+
+
+ );
+}
+// codeblock-focus-end
-navigation.dispatch(jumpToAction);
+function ProfileScreen({ route }) {
+ return (
+
+ Profile!
+ {route?.params?.user ? route.params.user : 'Noone'}'s profile
+
+ );
+}
+
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
```
+
+
+
diff --git a/versioned_docs/version-7.x/tab-based-navigation.md b/versioned_docs/version-7.x/tab-based-navigation.md
deleted file mode 100755
index f89d6fba80b..00000000000
--- a/versioned_docs/version-7.x/tab-based-navigation.md
+++ /dev/null
@@ -1,237 +0,0 @@
----
-id: tab-based-navigation
-title: Tab navigation
-sidebar_label: Tab navigation
----
-
-Possibly the most common style of navigation in mobile apps is tab-based navigation. This can be tabs on the bottom of the screen or on the top below the header (or even instead of a header).
-
-This guide covers [`createBottomTabNavigator`](bottom-tab-navigator.md). Before continuing, first install [`@react-navigation/bottom-tabs`](https://github.com/react-navigation/react-navigation/tree/main/packages/bottom-tabs):
-
-```bash npm2yarn
-npm install @react-navigation/bottom-tabs@next
-```
-
-## Minimal example of tab-based navigation
-
-
-
-```js
-import * as React from 'react';
-import { Text, View } from 'react-native';
-import { NavigationContainer } from '@react-navigation/native';
-import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
-
-function HomeScreen() {
- return (
-
- Home!
-
- );
-}
-
-function SettingsScreen() {
- return (
-
- Settings!
-
- );
-}
-
-const Tab = createBottomTabNavigator();
-
-export default function App() {
- return (
-
-
-
-
-
-
- );
-}
-```
-
-## Customizing the appearance
-
-This is similar to how you would customize a stack navigator — there are some properties that are set when you initialize the tab navigator and others that can be customized per-screen in `options`.
-
-
-
-```js
-// You can import Ionicons from @expo/vector-icons/Ionicons if you use Expo or
-// react-native-vector-icons/Ionicons otherwise.
-import Ionicons from 'react-native-vector-icons/Ionicons';
-
-// (...)
-
-export default function App() {
- return (
-
- ({
- tabBarIcon: ({ focused, color, size }) => {
- let iconName;
-
- if (route.name === 'Home') {
- iconName = focused
- ? 'ios-information-circle'
- : 'ios-information-circle-outline';
- } else if (route.name === 'Settings') {
- iconName = focused ? 'ios-list' : 'ios-list-outline';
- }
-
- // You can return any component that you like here!
- return ;
- },
- tabBarActiveTintColor: 'tomato',
- tabBarInactiveTintColor: 'gray',
- })}
- >
-
-
-
-
- );
-}
-```
-
-Let's dissect this:
-
-- `tabBarIcon` is a supported option in bottom tab navigator. So we know we can use it on our screen components in the `options` prop, but in this case chose to put it in the `screenOptions` prop of `Tab.Navigator` in order to centralize the icon configuration for convenience.
-- `tabBarIcon` is a function that is given the `focused` state, `color`, and `size` params. If you take a peek further down in the configuration you will see `tabBarActiveTintColor` and `tabBarInactiveTintColor`. These default to the iOS platform defaults, but you can change them here. The `color` that is passed through to the `tabBarIcon` is either the active or inactive one, depending on the `focused` state (focused is active). The `size` is the size of the icon expected by the tab bar.
-- Read the [full API reference](bottom-tab-navigator.md) for further information on `createBottomTabNavigator` configuration options.
-
-## Add badges to icons
-
-Sometimes we want to add badges to some icons. You can use the [`tabBarBadge` option](bottom-tab-navigator.md#tabbarbadge) to do it:
-
-
-
-```js
-
-```
-
-From UI perspective this component is ready to use, but you still need to find some way to pass down the badge count properly from somewhere else, like using [React Context](https://reactjs.org/docs/context.html), [Redux](https://redux.js.org/), [MobX](https://mobx.js.org/) or [event emitters](https://github.com/facebook/react-native/blob/master/Libraries/vendor/emitter/EventEmitter.js).
-
-
-
-## Jumping between tabs
-
-Switching from one tab to another has a familiar API — `navigation.navigate`.
-
-
-
-```js
-function HomeScreen({ navigation }) {
- return (
-
- Home!
- navigation.navigate('Settings')}
- />
-
- );
-}
-
-function SettingsScreen({ navigation }) {
- return (
-
- Settings!
- navigation.navigate('Home')} />
-
- );
-}
-```
-
-## A stack navigator for each tab
-
-Usually tabs don't just display one screen — for example, on your Twitter feed, you can tap on a tweet and it brings you to a new screen within that tab with all of the replies. You can think of this as there being separate navigation stacks within each tab, and that's exactly how we will model it in React Navigation.
-
-
-
-```js
-import * as React from 'react';
-import { Button, Text, View } from 'react-native';
-import { NavigationContainer } from '@react-navigation/native';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
-
-function DetailsScreen() {
- return (
-
- Details!
-
- );
-}
-
-function HomeScreen({ navigation }) {
- return (
-
- Home screen
- navigation.navigate('Details')}
- />
-
- );
-}
-
-function SettingsScreen({ navigation }) {
- return (
-
- Settings screen
- navigation.navigate('Details')}
- />
-
- );
-}
-
-const HomeStack = createNativeStackNavigator();
-
-function HomeStackScreen() {
- return (
-
-
-
-
- );
-}
-
-const SettingsStack = createNativeStackNavigator();
-
-function SettingsStackScreen() {
- return (
-
-
-
-
- );
-}
-
-const Tab = createBottomTabNavigator();
-
-export default function App() {
- return (
-
-
-
-
-
-
- );
-}
-```
-
-## Why do we need a TabNavigator instead of TabBarIOS or some other component?
-
-It's common to attempt to use a standalone tab bar component without integrating it into the navigation library you use in your app. In some cases, this works fine! You should be warned, however, that you may run into some frustrating unanticipated issues when doing this.
-
-For example, React Navigation's tab navigator takes care of handling the Android back button for you, while standalone components typically do not. Additionally, it is more difficult for you (as the developer) to perform actions such as "jump to this tab and then go to this screen" if you need to call into two distinct APIs for it. Lastly, mobile user interfaces have numerous small design details that require that certain components are aware of the layout or presence of other components — for example, if you have a translucent tab bar, content should scroll underneath it and the scroll view should have an inset on the bottom equal to the height of the tab bar so you can see all of the content. Double tapping the tab bar should make the active navigation stack pop to the top of the stack, and doing it again should scroll the active scroll view in that stack scroll to the top. While not all of these behaviors are implemented out of the box yet with React Navigation, they will be and you will not get any of this if you use a standalone tab view component.
-
-## A tab navigator contains a stack and you want to hide the tab bar on specific screens
-
-[See the documentation here](hiding-tabbar-in-screens.md)
diff --git a/versioned_docs/version-7.x/tab-view.md b/versioned_docs/version-7.x/tab-view.md
index 904d9c974cf..b1e13b3d2c2 100644
--- a/versioned_docs/version-7.x/tab-view.md
+++ b/versioned_docs/version-7.x/tab-view.md
@@ -8,9 +8,9 @@ React Native Tab View is a cross-platform Tab View component for React Native im
It follows material design guidelines by default, but you can also use your own custom tab bar or position the tab bar at the bottom.
-
-
-
+
+
+
This package doesn't integrate with React Navigation. If you want to integrate the tab view with React Navigation's navigation system, e.g. want to show screens in the tab bar and be able to navigate between them using `navigation.navigate` etc, use [Material Top Tab Navigator](material-top-tab-navigator.md) instead.
@@ -22,29 +22,44 @@ To use this package, open a Terminal in the project root and run:
npm install react-native-tab-view
```
-Next, install [`react-native-pager-view`](https://github.com/callstack/react-native-viewpager) if you plan to support iOS and Android.
+The library depends on [`react-native-pager-view`](https://github.com/callstack/react-native-pager-view) for rendering the pages.
-If you are using Expo, to ensure that you get the compatible versions of the libraries, run:
+
+
+
+If you have a Expo managed project, in your project directory, run:
```bash
-expo install react-native-pager-view
+npx expo install react-native-pager-view
```
-If you are not using Expo, run the following:
+
+
+
+If you have a bare React Native project, in your project directory, run:
```bash npm2yarn
npm install react-native-pager-view
```
-We're done! Now you can build and run the app on your device/simulator.
+
+
+
+If you're on a Mac and developing for iOS, you also need to install [pods](https://cocoapods.org/) to complete the linking.
+
+```bash
+npx pod-install ios
+```
## Quick start
-```js
+```js name="React Native Tab View" snack
+// codeblock-focus-start
import * as React from 'react';
import { View, useWindowDimensions } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
+// codeblock-focus-end
const FirstRoute = () => (
);
@@ -53,19 +68,20 @@ const SecondRoute = () => (
);
+// codeblock-focus-start
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
+const routes = [
+ { key: 'first', title: 'First' },
+ { key: 'second', title: 'Second' },
+];
+
export default function TabViewExample() {
const layout = useWindowDimensions();
-
const [index, setIndex] = React.useState(0);
- const [routes] = React.useState([
- { key: 'first', title: 'First' },
- { key: 'second', title: 'Second' },
- ]);
return (
);
}
+// codeblock-focus-end
```
-[Try this example on Snack](https://snack.expo.io/@satya164/react-native-tab-view-quick-start)
-
## More examples on Snack
- [Custom Tab Bar](https://snack.expo.io/@satya164/react-native-tab-view-custom-tabbar)
@@ -248,7 +263,7 @@ Position of the tab bar in the tab view. Possible values are `'top'` and `'botto
Function which takes an object with the current route and returns a boolean to indicate whether to lazily render the scenes.
-By default all scenes are rendered to provide a smoother swipe experience. But you might want to defer the rendering of unfocused scenes until the user sees them. To enable lazy rendering for a particular scene, return `true` from `getLazy` for that `route`:
+By default all scenes are rendered to provide a smoother swipe experience. But you might want to defer the rendering of unfocused scenes until the user sees them. To enable lazy rendering for a particular scene, return `true` from `lazy` for that `route`:
```js
+
```
##### `lazyPreloadDistance`
@@ -318,10 +331,6 @@ Object containing the initial height and width of the screens. Passing this will
Used to override default value of pager's overScroll mode. Can be `auto`, `always` or `never` (Android only).
-##### `sceneContainerStyle`
-
-Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping:
-
##### `pagerStyle`
Style to apply to the pager view wrapping all the scenes.
@@ -358,74 +367,6 @@ return (
#### TabBar Props
-##### `getLabelText`
-
-Function which takes an object with the current route and returns the label text for the tab. Uses `route.title` by default.
-
-```js
- route.title}
- ...
-/>
-```
-
-##### `getAccessible`
-
-Function which takes an object with the current route and returns a boolean to indicate whether to mark a tab as `accessible`. Defaults to `true`.
-
-##### `getAccessibilityLabel`
-
-Function which takes an object with the current route and returns a accessibility label for the tab button. Uses `route.accessibilityLabel` by default if specified, otherwise uses the route title.
-
-```js
- route.accessibilityLabel}
- ...
-/>
-```
-
-##### `getTestID`
-
-Function which takes an object with the current route and returns a test id for the tab button to locate this tab button in tests. Uses `route.testID` by default.
-
-```js
- route.testID}
- ...
-/>
-```
-
-##### `renderIcon`
-
-Function which takes an object with the current route, focused status and color and returns a custom React Element to be used as a icon.
-
-```js
- (
-
- )}
- ...
-/>
-```
-
-##### `renderLabel`
-
-Function which takes an object with the current route, focused status and color and returns a custom React Element to be used as a label.
-
-```js
- (
-
- {route.title}
-
- )}
- ...
-/>
-```
-
##### `renderTabBarItem`
Function which takes a `TabBarItemProps` object and returns a custom React Element to be used as a tab button.
@@ -434,10 +375,6 @@ Function which takes a `TabBarItemProps` object and returns a custom React Eleme
Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
-##### `renderBadge`
-
-Function which takes an object with the current route and returns a custom React Element to be used as a badge.
-
##### `onTabPress`
Function to execute on tab press. It receives the scene for the pressed tab, useful for things like scroll to top.
@@ -501,10 +438,6 @@ Style to apply to the active indicator.
Style to apply to the container view for the indicator.
-##### `labelStyle`
-
-Style to apply to the tab item label.
-
##### `contentContainerStyle`
Style to apply to the inner container for tabs.
@@ -515,11 +448,118 @@ Style to apply to the tab bar container.
##### `gap`
-Define a spacing between tabs.
+Spacing between the tab items.
+
+##### `testID` (`TabBar`)
+
+Test ID for the tab bar. Can be used for scrolling the tab bar in tests
+
+#### Options
+
+Options describe how each tab should be configured. There are 2 ways to specify options:
+
+- `commonOptions`: Options that apply to all tabs.
+- `options`: Options that apply to specific tabs. It has the route key as the key and the object with options.
+
+Example:
+
+```js
+ (
+
+ ),
+ }}
+ options={{
+ albums: {
+ labelText: 'Albums',
+ },
+ profile: {
+ labelText: 'Profile',
+ },
+ }}
+/>
+```
+
+The following options are available:
+
+##### `accessibilityLabel`
+
+Accessibility label for the tab button. Uses `route.accessibilityLabel` by default if specified, otherwise uses the route title.
+
+##### `accessible`
+
+Whether to mark the tab as `accessible`. Defaults to `true`.
##### `testID`
-Test id for the tabBar. Can be used for scrolling the tab bar in tests
+Test ID for the tab button. Uses `route.testID` by default.
+
+##### `labelText`
+
+Label text for the tab button. Uses `route.title` by default.
+
+##### `labelAllowFontScaling`
+
+Whether label font should scale to respect Text Size accessibility settings. Defaults to `true`.
+
+##### `href`
+
+URL to use for the anchor tag for the tab button on the Web.
+
+##### `label`
+
+A function that returns a custom React Element to be used as a label. The function receives an object with the following properties:
+
+- `route` - The route object for the tab.
+- `labelText` - The label text for the tab specified in the `labelText` option or the `route title`.
+- `focused` - Whether the label is for the focused state.
+- `color` - The color of the label.
+- `allowFontScaling` - Whether label font should scale to respect Text Size accessibility settings.
+- `style` - The style object for the label.
+
+```js
+label: ({ route, labelText, focused, color }) => (
+ {labelText ?? route.name}
+);
+```
+
+##### `labelStyle`
+
+Style to apply to the tab item label.
+
+##### `icon`
+
+A function that returns a custom React Element to be used as an icon. The function receives an object with the following properties:
+
+- `route` - The route object for the tab.
+- `focused` - Whether the icon is for the focused state.
+- `color` - The color of the icon.
+- `size` - The size of the icon.
+
+```js
+icon: ({ route, focused, color }) => (
+
+);
+```
+
+##### `badge`
+
+A function that returns a custom React Element to be used as a badge. The function receives an object with the following properties:
+
+- `route` - The route object for the tab.
+
+```js
+badge: ({ route }) => (
+
+);
+```
+
+##### `sceneStyle`
+
+Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping.
## Optimization Tips
diff --git a/versioned_docs/version-7.x/testing.md b/versioned_docs/version-7.x/testing.md
index 1930583107f..a39c33b1fdb 100644
--- a/versioned_docs/version-7.x/testing.md
+++ b/versioned_docs/version-7.x/testing.md
@@ -1,88 +1,957 @@
---
id: testing
-title: Testing with Jest
-sidebar_label: Testing with Jest
+title: Writing tests
+sidebar_label: Writing tests
---
-Testing code using React Navigation may require some setup since we need to mock native dependencies used in the navigators. We recommend using [Jest](https://jestjs.io) to write unit tests.
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
-## Mocking native modules
+React Navigation components can be tested in a similar way to other React components. This guide will cover how to write tests for components using React Navigation using [Jest](https://jestjs.io).
+
+## Guiding principles
+
+When writing tests, it's encouraged to write tests that closely resemble how users interact with your app. Keeping this in mind, here are some guiding principles to follow:
+
+- **Test the result, not the action**: Instead of checking if a specific navigation action was called, check if the expected components are rendered after navigation.
+- **Avoid mocking React Navigation**: Mocking React Navigation components can lead to tests that don't match the actual logic. Instead, use a real navigator in your tests.
+
+Following these principles will help you write tests that are more reliable and easier to maintain by avoiding testing implementation details.
+
+## Setting up Jest
+
+### Compiling React Navigation
+
+React Navigation ships [ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). However, Jest does not support ES modules natively.
+
+It's necessary to transform the code to CommonJS to use them in tests. The `react-native` preset for Jest does not transform the code in `node_modules` by default. To enable this, you need to add the [`transformIgnorePatterns`](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring) option in your Jest configuration where you can specify a regexp pattern. To compile React Navigation packages, you can add `@react-navigation` to the regexp.
+
+This is usually done in a `jest.config.js` file or the `jest` key in `package.json`:
+
+```diff lang=json
+{
+ "preset": "react-native",
++ "transformIgnorePatterns": [
++ "node_modules/(?!(@react-native|react-native|@react-navigation)/)"
++ ]
+}
+```
+
+### Mocking native dependencies
To be able to test React Navigation components, certain dependencies will need to be mocked depending on which components are being used.
-If you're using `@react-navigation/drawer`, you will need to mock:
+If you're using `@react-navigation/stack`, you will need to mock:
-- `react-native-reanimated`
- `react-native-gesture-handler`
-If you're using `@react-navigation/stack`, you will only need to mock:
+If you're using `@react-navigation/drawer`, you will need to mock:
+- `react-native-reanimated`
- `react-native-gesture-handler`
To add the mocks, create a file `jest/setup.js` (or any other file name of your choice) and paste the following code in it:
```js
-// include this line for mocking react-native-gesture-handler
+// Include this line for mocking react-native-gesture-handler
import 'react-native-gesture-handler/jestSetup';
-// include this section and the NativeAnimatedHelper section for mocking react-native-reanimated
-jest.mock('react-native-reanimated', () => {
- const Reanimated = require('react-native-reanimated/mock');
+// Include this section for mocking react-native-reanimated
+import { setUpTests } from 'react-native-reanimated';
- // The mock for `call` immediately calls the callback which is incorrect
- // So we override it with a no-op
- Reanimated.default.call = () => {};
-
- return Reanimated;
-});
+setUpTests();
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
+import { jest } from '@jest/globals';
+
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
```
-Then we need to use this setup file in our jest config. You can add it under `setupFiles` option in a `jest.config.js` file or the `jest` key in `package.json`:
+Then we need to use this setup file in our jest config. You can add it under [`setupFilesAfterEnv`](https://jestjs.io/docs/configuration#setupfilesafterenv-array) option in a `jest.config.js` file or the `jest` key in `package.json`:
-```json
+```diff lang=json
{
"preset": "react-native",
- "setupFiles": [
- "/jest/setup.js"
+ "transformIgnorePatterns": [
+ "node_modules/(?!(@react-native|react-native|@react-navigation)/)"
],
++ "setupFilesAfterEnv": ["/jest/setup.js"]
}
```
-Make sure that the path to the file in `setupFiles` is correct. Jest will run these files before running your tests, so it's the best place to put your global mocks.
+Jest will run the files specified in `setupFilesAfterEnv` before running your tests, so it's a good place to put your global mocks.
+
+
+Mocking `react-native-screens`
+
+This shouldn't be necessary in most cases. However, if you find yourself in a need to mock `react-native-screens` component for some reason, you should do it by adding following code in `jest/setup.js` file:
+
+```js
+// Include this section for mocking react-native-screens
+jest.mock('react-native-screens', () => {
+ // Require actual module instead of a mock
+ let screens = jest.requireActual('react-native-screens');
+
+ // All exports in react-native-screens are getters
+ // We cannot use spread for cloning as it will call the getters
+ // So we need to clone it with Object.create
+ screens = Object.create(
+ Object.getPrototypeOf(screens),
+ Object.getOwnPropertyDescriptors(screens)
+ );
+
+ // Add mock of the component you need
+ // Here is the example of mocking the Screen component as a View
+ Object.defineProperty(screens, 'Screen', {
+ value: require('react-native').View,
+ });
+
+ return screens;
+});
+```
+
+
If you're not using Jest, then you'll need to mock these modules according to the test framework you are using.
-## Writing tests
+## Fake timers
+
+When writing tests containing navigation with animations, you need to wait until the animations finish. In such cases, we recommend using [`Fake Timers`](https://jestjs.io/docs/timer-mocks) to simulate the passage of time in your tests. This can be done by adding the following line at the beginning of your test file:
+
+```js
+jest.useFakeTimers();
+```
-We recommend using [React Native Testing Library](https://callstack.github.io/react-native-testing-library/) along with [`jest-native`](https://github.com/testing-library/jest-native) to write your tests.
+Fake timers replace real implementation of the native timer functions (e.g. `setTimeout()`, `setInterval()` etc,) with a custom implementation that uses a fake clock. This lets you instantly skip animations and reduce the time needed to run your tests by calling methods such as `jest.runAllTimers()`.
-Example:
+Often, component state is updated after an animation completes. To avoid getting an error in such cases, wrap `jest.runAllTimers()` in `act`:
```js
-import * as React from 'react';
-import { screen, render, fireEvent } from '@testing-library/react-native';
+import { act } from 'react-test-renderer';
+
+// ...
+
+act(() => jest.runAllTimers());
+```
+
+See the examples below for more details on how to use fake timers in tests involving navigation.
+
+## Navigation and visibility
+
+In React Navigation, the previous screen is not unmounted when navigating to a new screen. This means that the previous screen is still present in the component tree, but it's not visible.
+
+When writing tests, you should assert that the expected component is visible or hidden instead of checking if it's rendered or not. React Native Testing Library provides a `toBeVisible` matcher that can be used to check if an element is visible to the user.
+
+```js
+expect(screen.getByText('Settings screen')).toBeVisible();
+```
+
+This is in contrast to the `toBeOnTheScreen` matcher, which checks if the element is rendered in the component tree. This matcher is not recommended when writing tests involving navigation.
+
+By default, the queries from React Native Testing Library (e.g. `getByRole`, `getByText`, `getByLabelText` etc.) [only return visible elements](https://callstack.github.io/react-native-testing-library/docs/api/queries#includehiddenelements-option). So you don't need to do anything special. However, if you're using a different library for your tests, you'll need to account for this behavior.
+
+## Example tests
+
+We recommend using [React Native Testing Library](https://callstack.github.io/react-native-testing-library/) to write your tests.
+
+In this guide, we will go through some example scenarios and show you how to write tests for them using Jest and React Native Testing Library:
+
+### Navigation between tabs
+
+In this example, we have a bottom tab navigator with two tabs: Home and Settings. We will write a test that asserts that we can navigate between these tabs by pressing the tab bar buttons.
+
+
+
+
+```js title="MyTabs.js"
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Text, View } from 'react-native';
+
+const HomeScreen = () => {
+ return (
+
+ Home screen
+
+ );
+};
+
+const SettingsScreen = () => {
+ return (
+
+ Settings screen
+
+ );
+};
+
+export const MyTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Settings: SettingsScreen,
+ },
+});
+```
+
+
+
+
+```js title="MyTabs.js"
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Text, View } from 'react-native';
+
+const HomeScreen = () => {
+ return (
+
+ Home screen
+
+ );
+};
+
+const SettingsScreen = () => {
+ return (
+
+ Settings screen
+
+ );
+};
+
+const Tab = createBottomTabNavigator();
+
+export const MyTabs = () => {
+ return (
+
+
+
+
+ );
+};
+```
+
+
+
+
+
+
+
+```js title="MyTabs.test.js"
+import { expect, jest, test } from '@jest/globals';
+import { createStaticNavigation } from '@react-navigation/native';
+import { act, render, screen, userEvent } from '@testing-library/react-native';
+
+import { MyTabs } from './MyTabs';
+
+jest.useFakeTimers();
+
+test('navigates to settings by tab bar button press', async () => {
+ const user = userEvent.setup();
+
+ const Navigation = createStaticNavigation(MyTabs);
+
+ render( );
+
+ const button = screen.getByRole('button', { name: 'Settings, tab, 2 of 2' });
+
+ await user.press(button);
+
+ act(() => jest.runAllTimers());
+
+ expect(screen.getByText('Settings screen')).toBeVisible();
+});
+```
+
+
+
+
+```js title="MyTabs.test.js"
+import { expect, jest, test } from '@jest/globals';
+import { NavigationContainer } from '@react-navigation/native';
+import { act, render, screen, userEvent } from '@testing-library/react-native';
+
+import { MyTabs } from './MyTabs';
+
+jest.useFakeTimers();
+
+test('navigates to settings by tab bar button press', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+ );
+
+ const button = screen.getByLabelText('Settings, tab, 2 of 2');
+
+ await user.press(button);
+
+ act(() => jest.runAllTimers());
+
+ expect(screen.getByText('Settings screen')).toBeVisible();
+});
+```
+
+
+
+
+In the above test, we:
+
+- Render the `MyTabs` navigator within a [NavigationContainer](navigation-container.md) in our test.
+- Get the tab bar button using the `getByLabelText` query that matches its accessibility label.
+- Press the button using `userEvent.press(button)` to simulate a user interaction.
+- Run all timers using `jest.runAllTimers()` to skip animations (e.g. animations in the `Pressable` for the button).
+- Assert that the `Settings screen` is visible after the navigation.
+
+### Reacting to a navigation event
+
+In this example, we have a stack navigator with two screens: Home and Surprise. We will write a test that asserts that the text "Surprise!" is displayed after navigating to the Surprise screen.
+
+
+
+
+```js title="MyStack.js"
+import { useNavigation } from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button, Text, View } from 'react-native';
+import { useEffect, useState } from 'react';
+
+const HomeScreen = () => {
+ const navigation = useNavigation();
+
+ return (
+
+ Home screen
+ navigation.navigate('Surprise')}
+ title="Click here!"
+ />
+
+ );
+};
+
+const SurpriseScreen = () => {
+ const navigation = useNavigation();
+
+ const [textVisible, setTextVisible] = useState(false);
+
+ useEffect(() => {
+ navigation.addListener('transitionEnd', () => setTextVisible(true));
+ }, [navigation]);
+
+ return (
+
+ {textVisible ? Surprise! : ''}
+
+ );
+};
+
+export const MyStack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Surprise: SurpriseScreen,
+ },
+});
+```
+
+
+
+
+```js title="MyStack.js"
+import { useNavigation } from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { useEffect, useState } from 'react';
+import { Button, Text, View } from 'react-native';
+
+const HomeScreen = () => {
+ const navigation = useNavigation();
+
+ return (
+
+ Home screen
+ navigation.navigate('Surprise')}
+ title="Click here!"
+ />
+
+ );
+};
+
+const SurpriseScreen = () => {
+ const navigation = useNavigation();
+
+ const [textVisible, setTextVisible] = useState(false);
+
+ useEffect(() => {
+ navigation.addListener('transitionEnd', () => setTextVisible(true));
+ }, [navigation]);
+
+ return (
+
+ {textVisible ? Surprise! : ''}
+
+ );
+};
+
+const Stack = createStackNavigator();
+
+export const MyStack = () => {
+ return (
+
+
+
+
+ );
+};
+```
+
+
+
+
+
+
+
+```js title="MyStack.test.js"
+import { expect, jest, test } from '@jest/globals';
+import { createStaticNavigation } from '@react-navigation/native';
+import { act, render, screen, userEvent } from '@testing-library/react-native';
+
+import { MyStack } from './MyStack';
+
+jest.useFakeTimers();
+
+test('shows surprise text after navigating to surprise screen', async () => {
+ const user = userEvent.setup();
+
+ const Navigation = createStaticNavigation(MyStack);
+
+ render( );
+
+ await user.press(screen.getByLabelText('Click here!'));
+
+ act(() => jest.runAllTimers());
+
+ expect(screen.getByText('Surprise!')).toBeVisible();
+});
+```
+
+
+
+
+```js title="MyStack.test.js"
+import { expect, jest, test } from '@jest/globals';
import { NavigationContainer } from '@react-navigation/native';
-import { RootNavigator } from './RootNavigator';
+import { act, render, screen, userEvent } from '@testing-library/react-native';
+
+import { MyStack } from './MyStack';
+
+jest.useFakeTimers();
+
+test('shows surprise text after navigating to surprise screen', async () => {
+ const user = userEvent.setup();
-test('shows profile screen when View Profile is pressed', () => {
render(
-
+
);
- fireEvent.press(screen.getByText('View Profile'));
+ await user.press(screen.getByLabelText('Click here!'));
+
+ act(() => jest.runAllTimers());
- expect(screen.getByText('My Profile')).toBeOnTheScreen();
+ expect(screen.getByText('Surprise!')).toBeVisible();
});
```
+
+
+
+In the above test, we:
+
+- Render the `MyStack` navigator within a [NavigationContainer](navigation-container.md) in our test.
+- Get the button using the `getByLabelText` query that matches its title.
+- Press the button using `userEvent.press(button)` to simulate a user interaction.
+- Run all timers using `jest.runAllTimers()` to skip animations (e.g. navigation animation between screens).
+- Assert that the `Surprise!` text is visible after the transition to the Surprise screen is complete.
+
+### Fetching data with `useFocusEffect`
+
+In this example, we have a bottom tab navigator with two tabs: Home and Pokemon. We will write a test that asserts the data fetching logic on focus in the Pokemon screen.
+
+
+
+
+```js title="MyTabs.js"
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { useFocusEffect } from '@react-navigation/native';
+import { useCallback, useState } from 'react';
+import { Text, View } from 'react-native';
+
+function HomeScreen() {
+ return (
+
+ Home screen
+
+ );
+}
+
+const url = 'https://pokeapi.co/api/v2/pokemon/ditto';
+
+function PokemonScreen() {
+ const [profileData, setProfileData] = useState({ status: 'loading' });
+
+ useFocusEffect(
+ useCallback(() => {
+ if (profileData.status === 'success') {
+ return;
+ }
+
+ setProfileData({ status: 'loading' });
+
+ const controller = new AbortController();
+
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(url, { signal: controller.signal });
+ const data = await response.json();
+
+ setProfileData({ status: 'success', data: data });
+ } catch (error) {
+ setProfileData({ status: 'error' });
+ }
+ };
+
+ fetchUser();
+
+ return () => {
+ controller.abort();
+ };
+ }, [profileData.status])
+ );
+
+ if (profileData.status === 'loading') {
+ return (
+
+ Loading...
+
+ );
+ }
+
+ if (profileData.status === 'error') {
+ return (
+
+ An error occurred!
+
+ );
+ }
+
+ return (
+
+ {profileData.data.name}
+
+ );
+}
+
+export const MyTabs = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Pokemon: PokemonScreen,
+ },
+});
+```
+
+
+
+
+```js title="MyTabs.js"
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { useFocusEffect } from '@react-navigation/native';
+import { useCallback, useState } from 'react';
+import { Text, View } from 'react-native';
+
+function HomeScreen() {
+ return (
+
+ Home screen
+
+ );
+}
+
+const url = 'https://pokeapi.co/api/v2/pokemon/ditto';
+
+function PokemonInfoScreen() {
+ const [profileData, setProfileData] = useState({ status: 'loading' });
+
+ useFocusEffect(
+ useCallback(() => {
+ if (profileData.status === 'success') {
+ return;
+ }
+
+ setProfileData({ status: 'loading' });
+
+ const controller = new AbortController();
+
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(url, { signal: controller.signal });
+ const data = await response.json();
+
+ setProfileData({ status: 'success', data: data });
+ } catch (error) {
+ setProfileData({ status: 'error' });
+ }
+ };
+
+ fetchUser();
+
+ return () => {
+ controller.abort();
+ };
+ }, [profileData.status])
+ );
+
+ if (profileData.status === 'loading') {
+ return (
+
+ Loading...
+
+ );
+ }
+
+ if (profileData.status === 'error') {
+ return (
+
+ An error occurred!
+
+ );
+ }
+
+ return (
+
+ {profileData.data.name}
+
+ );
+}
+
+const Tab = createBottomTabNavigator();
+
+export function MyTabs() {
+ return (
+
+
+
+
+ );
+}
+```
+
+
+
+
+To make the test deterministic and isolate it from the real backend, you can mock the network requests with a library such as [Mock Service Worker](https://mswjs.io/):
+
+```js title="msw-handlers.js"
+import { delay, http, HttpResponse } from 'msw';
+
+export const handlers = [
+ http.get('https://pokeapi.co/api/v2/pokemon/ditto', async () => {
+ await delay(1000);
+
+ return HttpResponse.json({
+ id: 132,
+ name: 'ditto',
+ });
+ }),
+];
+```
+
+Here we setup a handler that mocks responses from the API (for this example we're using [PokéAPI](https://pokeapi.co/)). Additionally, we `delay` the response by 1000ms to simulate a network request delay.
+
+Then, we write a Node.js integration module to use the Mock Service Worker in our tests:
+
+```js title="msw-node.js"
+import { setupServer } from 'msw/node';
+import { handlers } from './msw-handlers';
+
+const server = setupServer(...handlers);
+```
+
+Refer to the documentation of the library to learn more about setting it up in your project - [Getting started](https://mswjs.io/docs/getting-started), [React Native integration](https://mswjs.io/docs/integrations/react-native).
+
+
+
+
+```js title="MyTabs.test.js"
+import './msw-node';
+
+import { expect, jest, test } from '@jest/globals';
+import { createStaticNavigation } from '@react-navigation/native';
+import { act, render, screen, userEvent } from '@testing-library/react-native';
+
+import { MyTabs } from './MyTabs';
+
+jest.useFakeTimers();
+
+test('loads data on Pokemon info screen after focus', async () => {
+ const user = userEvent.setup();
+
+ const Navigation = createStaticNavigation(MyTabs);
+
+ render( );
+
+ const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2');
+ const profileTabButton = screen.getByLabelText('Profile, tab, 2 of 2');
+
+ await user.press(profileTabButton);
+
+ expect(screen.getByText('Loading...')).toBeVisible();
+
+ await act(() => jest.runAllTimers());
+
+ expect(screen.getByText('ditto')).toBeVisible();
+
+ await user.press(homeTabButton);
+
+ await act(() => jest.runAllTimers());
+
+ await user.press(profileTabButton);
+
+ expect(screen.queryByText('Loading...')).not.toBeVisible();
+ expect(screen.getByText('ditto')).toBeVisible();
+});
+```
+
+
+
+
+```js title="MyTabs.test.js"
+import './msw-node';
+
+import { expect, jest, test } from '@jest/globals';
+import { NavigationContainer } from '@react-navigation/native';
+import { act, render, screen, userEvent } from '@testing-library/react-native';
+
+import { MyTabs } from './MyTabs';
+
+jest.useFakeTimers();
+
+test('loads data on Pokemon info screen after focus', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+ );
+
+ const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2');
+ const profileTabButton = screen.getByLabelText('Profile, tab, 2 of 2');
+
+ await user.press(profileTabButton);
+
+ expect(screen.getByText('Loading...')).toBeVisible();
+
+ await act(() => jest.runAllTimers());
+
+ expect(screen.getByText('ditto')).toBeVisible();
+
+ await user.press(homeTabButton);
+
+ await act(() => jest.runAllTimers());
+
+ await user.press(profileTabButton);
+
+ expect(screen.queryByText('Loading...')).not.toBeVisible();
+ expect(screen.getByText('ditto')).toBeVisible();
+});
+```
+
+
+
+
+In the above test, we:
+
+- Assert that the `Loading...` text is visible while the data is being fetched.
+- Run all timers using `jest.runAllTimers()` to skip delays in the network request.
+- Assert that the `ditto` text is visible after the data is fetched.
+- Press the home tab button to navigate to the home screen.
+- Run all timers using `jest.runAllTimers()` to skip animations (e.g. animations in the `Pressable` for the button).
+- Press the profile tab button to navigate back to the Pokemon screen.
+- Ensure that cached data is shown by asserting that the `Loading...` text is not visible and the `ditto` text is visible.
+
+:::note
+
+In a production app, we recommend using a library like [React Query](https://tanstack.com/query/) to handle data fetching and caching. The above example is for demonstration purposes only.
+
+:::
+
+### Re-usable components
+
+To make it easier to test components that don't depend on the navigation structure, we can create a light-weight test navigator:
+
+```js title="TestStackNavigator.js"
+import { useNavigationBuilder, StackRouter } from '@react-navigation/native';
+
+function TestStackNavigator(props) {
+ const { state, descriptors, NavigationContent } = useNavigationBuilder(
+ StackRouter,
+ props
+ );
+
+ return (
+
+ {state.routes.map((route, index) => {
+ return (
+
+ {descriptors[route.key].render()}
+
+ );
+ })}
+
+ );
+}
+
+export function createTestStackNavigator(config) {
+ return createNavigatorFactory(TestStackNavigator)(config);
+}
+```
+
+This lets us test React Navigation specific logic such as `useFocusEffect` without needing to set up a full navigator.
+
+We can use this test navigator in our tests like this:
+
+
+
+
+```js title="MyComponent.test.js"
+import { act, render, screen } from '@testing-library/react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createTestStackNavigator } from './TestStackNavigator';
+import { MyComponent } from './MyComponent';
+
+test('does not show modal when not focused', () => {
+ const TestStack = createTestStackNavigator({
+ screens: {
+ A: MyComponent,
+ B: () => null,
+ },
+ });
+
+ const Navigation = createStaticNavigation(TestStack);
+
+ render(
+
+ );
+
+ expect(screen.queryByText('Modal')).not.toBeVisible();
+});
+
+test('shows modal when focused', () => {
+ const TestStack = createTestStackNavigator({
+ screens: {
+ A: MyComponent,
+ B: () => null,
+ },
+ });
+
+ const Navigation = createStaticNavigation(TestStack);
+
+ render(
+
+ );
+
+ expect(screen.getByText('Modal')).toBeVisible();
+});
+```
+
+
+
+
+```js title="MyComponent.test.js"
+import { act, render, screen } from '@testing-library/react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createTestStackNavigator } from './TestStackNavigator';
+import { MyComponent } from './MyComponent';
+
+test('does not show modal when not focused', () => {
+ const Stack = createTestStackNavigator();
+
+ const TestStack = () => (
+
+
+ null} />
+
+ );
+
+ render(
+
+
+
+ );
+
+ expect(screen.queryByText('Modal')).not.toBeVisible();
+});
+
+test('shows modal when focused', () => {
+ const Stack = createTestStackNavigator();
+
+ const TestStack = () => (
+
+
+ null} />
+
+ );
+
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('Modal')).toBeVisible();
+});
+```
+
+
+
+
+Here we create a test stack navigator using the `createTestStackNavigator` function. We then render the `MyComponent` component within the test navigator and assert that the modal is shown or hidden based on the focus state.
+
+The `initialState` prop is used to set the initial state of the navigator, i.e. which screens are rendered in the stack and which one is focused. See [navigation state](navigation-state.md) for more information on the structure of the state object.
+
+You can also pass a [`ref`](navigation-container.md#ref) to programmatically navigate in your tests.
+
+The test navigator is a simplified version of the stack navigator, but it's still a real navigator and behaves like one. This means that you can use it to test any other navigation logic.
+
+See [Custom navigators](custom-navigators.md) for more information on how to write custom navigators if you want adjust the behavior of the test navigator or add more functionality.
+
## Best practices
-There are a couple of things to keep in mind when writing tests for components using React Navigation:
+Generally, we recommend avoiding mocking React Navigation. Mocking can help you isolate the component you're testing, but when testing components with navigation logic, mocking means that your tests don't test for the navigation logic.
+
+- Mocking APIs such as `useFocusEffect` means you're not testing the focus logic in your component.
+- Mocking `navigation` prop or `useNavigation` means that the `navigation` object may not have the same shape as the real one.
+- Asserting `navigation.navigate` calls means you only test that the function was called, not that the call was correct based on the navigation structure.
+- etc.
+
+Avoiding mocks means additional work when writing tests, but it also means:
+
+- Refactors that don't change the logic won't break the tests, e.g. changing `navigation` prop to `useNavigation`, using a different navigation action that does the same thing, etc.
+- Library upgrades or refactor that actually change the behavior will correctly break the tests, surfacing actual regressions.
-1. Avoid mocking React Navigation. Instead, use a real navigator in your tests.
-2. Don't check for navigation actions. Instead, check for the result of the navigation such as the screen being rendered.
+Tests should break when there's a regression, not due to a refactor. Otherwise it leads to additional work to fix the tests, making it harder to know when a regression is introduced.
diff --git a/versioned_docs/version-7.x/themes.md b/versioned_docs/version-7.x/themes.md
index 08207935a2d..9d431ccded6 100755
--- a/versioned_docs/version-7.x/themes.md
+++ b/versioned_docs/version-7.x/themes.md
@@ -4,6 +4,9 @@ title: Themes
sidebar_label: Themes
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Themes allow you to change the colors and fonts of various components provided by React Navigation. You can use themes to:
- Customize the colors and fonts to match your brand
@@ -13,27 +16,212 @@ Themes allow you to change the colors and fonts of various components provided b
To pass a custom theme, you can pass the `theme` prop to the navigation container.
-
+
+
-```js
+```js name="Simple theme" snack
+// codeblock-focus-start
+import * as React from 'react';
+import {
+ useNavigation,
+ createStaticNavigation,
+ DefaultTheme,
+} from '@react-navigation/native';
+// codeblock-focus-end
+import { View, Text } from 'react-native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+
+const MyTheme = {
+ ...DefaultTheme,
+ colors: {
+ ...DefaultTheme.colors,
+ background: 'rgb(140, 201, 125)',
+ primary: 'rgb(255, 45, 85)',
+ },
+};
+// codeblock-focus-end
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+ const { user } = route.params;
+ return (
+
+ Settings Screen
+ userParam: {JSON.stringify(user)}
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile Screen
+
+ );
+}
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+
+ navigation.navigate('Panel', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const PanelStack = createNativeStackNavigator({
+ screens: {
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
+});
+
+const Drawer = createDrawerNavigator({
+ initialRouteName: 'Panel',
+ screens: {
+ Home: HomeScreen,
+ Panel: PanelStack,
+ },
+});
+
+// codeblock-focus-start
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ // highlight-next-line
+ return ;
+}
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Simple theme" snack
+// codeblock-focus-start
import * as React from 'react';
-import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
+import {
+ NavigationContainer,
+ DefaultTheme,
+ useNavigation,
+} from '@react-navigation/native';
+// codeblock-focus-end
+import { View, Text } from 'react-native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
const MyTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
+ background: 'rgb(140, 201, 125)',
primary: 'rgb(255, 45, 85)',
},
};
+// codeblock-focus-end
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+ const { user } = route.params;
+
+ return (
+
+ Settings Screen
+ userParam: {JSON.stringify(user)}
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ Home Screen
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+const Stack = createNativeStackNavigator();
+
+function Root() {
+ return (
+
+
+
+
+ );
+}
+
+// codeblock-focus-start
export default function App() {
return (
- {/* content */}
+ // highlight-next-line
+
+
+
+
+
+
);
}
+// codeblock-focus-start
```
+
+
+
You can change the theme prop dynamically and all the components will automatically update to reflect the new theme. If you haven't provided a `theme` prop, the default theme will be used.
## Properties
@@ -148,44 +336,307 @@ You can import the default and dark themes like so:
import { DefaultTheme, DarkTheme } from '@react-navigation/native';
```
+## Keeping the native theme in sync
+
+If you're changing the theme in the app, native UI elements such as Alert, ActionSheet etc. won't reflect the new theme. You can do the following to keep the native theme in sync:
+
+```js
+React.useEffect(() => {
+ const colorScheme = theme.dark ? 'dark' : 'light';
+
+ if (Platform.OS === 'web') {
+ document.documentElement.style.colorScheme = colorScheme;
+ } else {
+ Appearance.setColorScheme(colorScheme);
+ }
+}, [theme.dark]);
+```
+
+Alternatively, you can use the [`useColorScheme`](#using-the-operating-system-preferences) hook to get the current native color scheme and update the theme accordingly.
+
## Using the operating system preferences
-On iOS 13+ and Android 10+, you can get user's preferred color scheme (`'dark'` or `'light'`) with the ([Appearance API](https://reactnative.dev/docs/appearance)).
+On iOS 13+ and Android 10+, you can get user's preferred color scheme (`'dark'` or `'light'`) with the ([`useColorScheme` hook](https://reactnative.dev/docs/usecolorscheme)).
-
+
+
-```js
-import { useColorScheme } from 'react-native';
+```js name="Operating system color theme" snack
+import * as React from 'react';
+// codeblock-focus-start
+import {
+ useNavigation,
+ createStaticNavigation,
+ DefaultTheme,
+ DarkTheme,
+ useTheme,
+} from '@react-navigation/native';
+import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
+// codeblock-focus-end
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+ const { user } = route.params;
+ const { colors } = useTheme();
+
+ return (
+
+ Settings Screen
+
+ userParam: {JSON.stringify(user)}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const { colors } = useTheme();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+function MyButton() {
+ const { colors } = useTheme();
+
+ return (
+
+ Button!
+
+ );
+}
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const { colors } = useTheme();
+
+ return (
+
+ Home Screen
+
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const PanelStack = createNativeStackNavigator({
+ screens: {
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
+});
+
+const Drawer = createDrawerNavigator({
+ initialRouteName: 'Panel',
+ screens: {
+ Home: HomeScreen,
+ Panel: PanelStack,
+ },
+});
+
+// codeblock-focus-start
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ // highlight-next-line
+ const scheme = useColorScheme();
+
+ // highlight-next-line
+ return ;
+}
+
+// codeblock-focus-end
+```
+
+
+
+
+```js name="Operating system color theme" snack
+import * as React from 'react';
+// codeblock-focus-start
+import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
import {
NavigationContainer,
DefaultTheme,
DarkTheme,
+ useTheme,
} from '@react-navigation/native';
+// codeblock-focus-end
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
-export default () => {
+function SettingsScreen({ route, navigation }) {
+ const { user } = route.params;
+ const { colors } = useTheme();
+
+ return (
+
+ Settings Screen
+
+ userParam: {JSON.stringify(user)}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const { colors } = useTheme();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+function MyButton() {
+ const { colors } = useTheme();
+
+ return (
+
+ Button!
+
+ );
+}
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const { colors } = useTheme();
+
+ return (
+
+ Home Screen
+
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+const Stack = createNativeStackNavigator();
+
+function Root() {
+ return (
+
+
+
+
+ );
+}
+
+// codeblock-focus-start
+
+export default function App() {
+ // highlight-next-line
const scheme = useColorScheme();
return (
+ // highlight-next-line
- {/* content */}
+
+
+
+
);
-};
+}
+// codeblock-focus-end
```
+
+
+
## Using the current theme in your own components
To gain access to the theme in any component that is rendered inside the navigation container:, you can use the `useTheme` hook. It returns the theme object:
-
+
+
-```js
+```js name="System themes" snack
import * as React from 'react';
-import { TouchableOpacity, Text } from 'react-native';
-import { useTheme } from '@react-navigation/native';
+// codeblock-focus-start
+import {
+ useNavigation,
+ createStaticNavigation,
+ DefaultTheme,
+ DarkTheme,
+ useTheme,
+} from '@react-navigation/native';
+import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
+// codeblock-focus-end
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+ const { user } = route.params;
+ const { colors } = useTheme();
+
+ return (
+
+ Settings Screen
+
+ userParam: {JSON.stringify(user)}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const { colors } = useTheme();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+// codeblock-focus-start
-// Black background and white text in light theme, inverted on dark theme
function MyButton() {
+ // highlight-next-line
const { colors } = useTheme();
return (
@@ -194,4 +645,164 @@ function MyButton() {
);
}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const { colors } = useTheme();
+
+ return (
+
+ Home Screen
+
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const PanelStack = createNativeStackNavigator({
+ screens: {
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
+});
+
+const Drawer = createDrawerNavigator({
+ initialRouteName: 'Panel',
+ screens: {
+ Home: HomeScreen,
+ Panel: PanelStack,
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ const scheme = useColorScheme();
+
+ return ;
+}
```
+
+
+
+
+```js name="System themes" snack
+import * as React from 'react';
+// codeblock-focus-start
+import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
+import {
+ NavigationContainer,
+ DefaultTheme,
+ DarkTheme,
+ useTheme,
+ useNavigation,
+} from '@react-navigation/native';
+// codeblock-focus-end
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+
+function SettingsScreen({ route, navigation }) {
+ const { colors } = useTheme();
+ const { user } = route.params;
+
+ return (
+
+ Settings Screen
+
+ userParam: {JSON.stringify(user)}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const { colors } = useTheme();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+// codeblock-focus-start
+
+function MyButton() {
+ // highlight-next-line
+ const { colors } = useTheme();
+
+ return (
+
+ Button!
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const { colors } = useTheme();
+
+ return (
+
+ Home Screen
+
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+const Stack = createNativeStackNavigator();
+
+function Root() {
+ return (
+
+
+
+
+ );
+}
+
+export default function App() {
+ const scheme = useColorScheme();
+
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
diff --git a/versioned_docs/version-7.x/troubleshooting.md b/versioned_docs/version-7.x/troubleshooting.md
index 51436d92854..1186ea690eb 100755
--- a/versioned_docs/version-7.x/troubleshooting.md
+++ b/versioned_docs/version-7.x/troubleshooting.md
@@ -4,6 +4,9 @@ title: Troubleshooting
sidebar_label: Troubleshooting
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
This section attempts to outline issues that users frequently encounter when first getting accustomed to using React Navigation. These issues may or may not be related to React Navigation itself.
Before troubleshooting an issue, make sure that you have upgraded to **the latest available versions** of the packages. You can install the latest versions by installing the packages again (e.g. `npm install package-name`).
@@ -62,10 +65,10 @@ If it's missing these extensions, add them and then clear metro cache as shown i
## I'm getting "SyntaxError in @react-navigation/xxx/xxx.tsx" or "SyntaxError: /xxx/@react-navigation/xxx/xxx.tsx: Unexpected token"
-This might happen if you have an old version of the `metro-react-native-babel-preset` package. Try upgrading it to the latest version.
+This might happen if you have an old version of the `@react-native/babel-preset` package. Try upgrading it to the latest version.
```bash npm2yarn
-npm install --save-dev metro-react-native-babel-preset
+npm install --save-dev @react-native/babel-preset
```
If you have `@babel/core` installed, also upgrade it to latest version.
@@ -74,7 +77,7 @@ If you have `@babel/core` installed, also upgrade it to latest version.
npm install --save-dev @babel/core
```
-If upgrading the packages don't help, you can also try deleting your `node_modules` as well as lock the file and reinstall your dependencies.
+If upgrading the packages don't help, you can also try deleting your `node_modules` and then the lock the file and reinstall your dependencies.
If you use `npm`:
@@ -92,6 +95,12 @@ rm yarn.lock
yarn
```
+:::warning
+
+Deleting the lockfile is generally not recommended as it may upgrade your dependencies to versions that haven't been tested with your project. So only use this as a last resort.
+
+:::
+
After upgrading or reinstalling the packages, you should also clear Metro bundler's cache following the instructions earlier in the page.
## I'm getting "Module '[...]' has no exported member 'xxx' when using TypeScript
@@ -198,6 +207,31 @@ Now rebuild the app and test on your device or simulator.
If you wrap the container in a `View`, make sure the `View` stretches to fill the container using `flex: 1`:
+
+
+
+```js
+import * as React from 'react';
+import { View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+
+/* ... */
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return (
+ // highlight-next-line
+
+
+
+ );
+}
+```
+
+
+
+
```js
import * as React from 'react';
import { View } from 'react-native';
@@ -205,6 +239,7 @@ import { NavigationContainer } from '@react-navigation/native';
export default function App() {
return (
+ // highlight-next-line
{/* ... */}
@@ -212,18 +247,21 @@ export default function App() {
}
```
+
+
+
## I get the warning "Non-serializable values were found in the navigation state"
-This can happen if you are passing non-serializable values such as class instances, functions etc. in params. React Navigation warns you in this case because this can break other functionality such [state persistence](state-persistence.md), [deep linking](deep-linking.md) etc.
+This can happen if you are passing non-serializable values such as class instances, functions etc. in params. React Navigation warns you in this case because this can break other functionality such [state persistence](state-persistence.md), [deep linking](deep-linking.md), [web support](web-support.md) etc.
Example of some use cases for passing functions in params are the following:
- To pass a callback to use in a header button. This can be achieved using `navigation.setOptions` instead. See the [guide for header buttons](header-buttons.md#header-interaction-with-its-screen-component) for examples.
-- To pass a callback to the next screen which it can call to pass some data back. You can usually achieve it using `navigate` instead. See the [guide for params](params.md) for examples.
+- To pass a callback to the next screen which it can call to pass some data back. You can usually achieve it using `popTo` instead. See [passing params to a previous screen](params.md#passing-params-to-a-previous-screen) for examples.
- To pass complex data to another screen. Instead of passing the data `params`, you can store that complex data somewhere else (like a global store), and pass an id instead. Then the screen can get the data from the global store using the id. See [what should be in params](params.md#what-should-be-in-params).
- Pass data, callbacks etc. from a parent to child screens. You can either use React Context, or pass a children callback to pass these down instead of using params. See [passing additional props](hello-react-navigation.md#passing-additional-props).
-If you don't use state persistence or deep link to the screen which accepts functions in params, then the warning doesn't affect you and you can safely ignore it. To ignore the warning, you can use `LogBox.ignoreLogs`.
+We don't generally recommend passing functions in params. But if you don't use state persistence, deep links, or use React Navigation on Web, then you can choose to ignore it. To ignore the warning, you can use `LogBox.ignoreLogs`.
Example:
@@ -237,29 +275,80 @@ LogBox.ignoreLogs([
## I'm getting "Invalid hook call. Hooks can only be called inside of the body of a function component"
-This can happen when you pass a React component to an option that accepts a function returning a react element. For example, the [`headerTitle` option in native stack navigator](native-stack-navigator.md#headerTitle) expects a function returning a react element:
+This can happen when you pass a React component to an option that accepts a function returning a react element. For example, the [`headerTitle` option in native stack navigator](native-stack-navigator.md#headertitle) expects a function returning a react element:
+
+
+
+
+```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: Home,
+ options: {
+ // highlight-next-line
+ headerTitle: (props) => ,
+ },
+ },
+ },
+});
+```
+
+
+
```js
}}
+ option={{
+ // highlight-next-line
+ headerTitle: (props) => ,
+ }}
/>
```
+
+
+
If you directly pass a function here, you'll get this error when using hooks:
+
+
+
+```js
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: Home,
+ options: {
+ // This is not correct
+ // highlight-next-line
+ headerTitle: MyTitle,
+ },
+ },
+ },
+});
+```
+
+
+
+
```js
```
+
+
+
The same applies to other options like `headerLeft`, `headerRight`, `tabBarIcon` etc. as well as props such as `tabBar`, `drawerContent` etc.
## Screens are unmounting/remounting during navigation
@@ -289,6 +378,30 @@ Here, every time the component re-renders, a new function will be created and pa
Another easy to identify example of this is when you create a component inside another component:
+
+
+
+```js
+function App() {
+ const Home = () => {
+ return ;
+ };
+
+ const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: Home,
+ },
+ });
+
+ const Navigation = createStaticNavigation(RootStack);
+
+ return ;
+}
+```
+
+
+
+
```js
function App() {
const Home = () => {
@@ -303,6 +416,9 @@ function App() {
}
```
+
+
+
Or when you use a higher order component (such as `connect` from Redux, or `withX` functions that accept a component) inside another component:
```js
@@ -317,8 +433,36 @@ function App() {
If you're unsure, it's always best to make sure that the components you are using as screens are defined outside of a React component. They could be defined in another file and imported, or defined at the top level scope in the same file:
+
+
+
+```js
+const Home = () => {
+ // ...
+
+ return ;
+};
+
+const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: Home,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+function App() {
+ return ;
+}
+```
+
+
+
+
```js
const Home = () => {
+ // ...
+
return ;
};
@@ -331,6 +475,9 @@ function App() {
}
```
+
+
+
This is not React Navigation specific, but related to React in general. You should always avoid creating components during render, whether you are using React Navigation or not.
## App is not working properly when connected to Chrome Debugger
diff --git a/versioned_docs/version-7.x/typescript.md b/versioned_docs/version-7.x/typescript.md
index 87811b66434..72fd891716a 100755
--- a/versioned_docs/version-7.x/typescript.md
+++ b/versioned_docs/version-7.x/typescript.md
@@ -1,14 +1,156 @@
---
id: typescript
title: Type checking with TypeScript
-sidebar_label: Type checking with TypeScript
+sidebar_label: Configuring TypeScript
---
-React Navigation is written with TypeScript and exports type definitions for TypeScript projects.
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
-### Type checking the navigator
+React Navigation can be configured to type-check screens and their params, as well as various other APIs using TypeScript. This provides better intelliSense and type safety when working with React Navigation.
-To type check our route name and params, the first thing we need to do is to create an object type with mappings for route name to the params of the route. For example, say we have a route called `Profile` in our root navigator which should have a param `userId`:
+First, make sure you have the following configuration in your `tsconfig.json` under `compilerOptions`:
+
+- `strict: true` or `strictNullChecks: true` - Necessary for intelliSense and type inference to work correctly.
+- `moduleResolution: "bundler"` - Necessary to resolve the types correctly and match the behavior of [Metro](https://metrobundler.dev/) and other bundlers.
+
+
+
+
+There are 2 steps to configure TypeScript with the static API:
+
+1. Each screen component needs to specify the type of the [`route.params`](params.md) prop that it accepts. The `StaticScreenProps` type makes it simpler:
+
+ ```ts
+ import type { StaticScreenProps } from '@react-navigation/native';
+
+ // highlight-start
+ type Props = StaticScreenProps<{
+ username: string;
+ }>;
+ // highlight-end
+
+ function ProfileScreen({ route }: Props) {
+ // ...
+ }
+ ```
+
+2. Generate the `ParamList` type for the root navigator and specify it as the default type for the `RootParamList` type:
+
+ ```ts
+ import type { StaticParamList } from '@react-navigation/native';
+
+ const HomeTabs = createBottomTabNavigator({
+ screens: {
+ Feed: FeedScreen,
+ Profile: ProfileScreen,
+ },
+ });
+
+ const RootStack = createNativeStackNavigator({
+ screens: {
+ Home: HomeTabs,
+ },
+ });
+
+ // highlight-next-line
+ type RootStackParamList = StaticParamList;
+
+ // highlight-start
+ declare global {
+ namespace ReactNavigation {
+ interface RootParamList extends RootStackParamList {}
+ }
+ }
+ // highlight-end
+ ```
+
+ This is needed to type-check the [`useNavigation`](use-navigation.md) hook.
+
+## Navigator specific types
+
+Generally, we recommend using the default types for the [`useNavigation`](use-navigation.md) prop to access the navigation object in a navigator-agnostic manner. However, if you need to use navigator-specific APIs, e.g. `setOptions` to update navigator options, `push`, `pop`, `popTo` etc. with stacks, `openDrawer`, `closeDrawer` etc. with drawer and so on, you need to manually annotate [`useNavigation`](use-navigation.md):
+
+```ts
+import type { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
+
+type BottomTabParamList = StaticParamList;
+type ProfileScreenNavigationProp = BottomTabNavigationProp<
+ BottomTabParamList,
+ 'Profile'
+>;
+
+// ...
+
+const navigation = useNavigation();
+```
+
+Similarly, you can import `NativeStackNavigationProp` from [`@react-navigation/native-stack`](native-stack-navigator.md), `StackNavigationProp` from [`@react-navigation/stack`](stack-navigator.md), `DrawerNavigationProp` from [`@react-navigation/drawer`](drawer-navigator.md) etc.
+
+:::danger
+
+Annotating [`useNavigation`](use-navigation.md) this way is not type-safe since we can't guarantee that the type you provided matches the type of the navigator. So try to keep manual annotations to a minimum and use the default types instead.
+
+:::
+
+## Nesting navigator using dynamic API
+
+Consider the following example:
+
+```js
+const Tab = createBottomTabNavigator();
+
+function HomeTabs() {
+ return (
+
+
+
+
+ );
+}
+
+const RootStack = createStackNavigator({
+ Home: HomeTabs,
+});
+```
+
+Here, the `HomeTabs` component is defined using the dynamic API. This means that when we create the param list for the root navigator with `StaticParamList`, it won't know about the screens defined in the nested navigator. To fix this, we'd need to specify the param list for the nested navigator explicitly.
+
+This can be done by using the type of the [`route`](route-object.md) prop that the screen component receives:
+
+```ts
+type HomeTabsParamList = {
+ Feed: undefined;
+ Profile: undefined;
+};
+
+// highlight-start
+type HomeTabsProps = StaticScreenProps<
+ NavigatorScreenParams
+>;
+// highlight-end
+
+// highlight-next-line
+function HomeTabs(_: HomeTabsProps) {
+ return (
+
+
+
+
+ );
+}
+```
+
+Now, when using `StaticParamList`, it will include the screens defined in the nested navigator.
+
+
+
+
+When using the dynamic API, it is necessary to specify the types for each screen as well as the nesting structure as it cannot be inferred from the code.
+
+## Typechecking the navigator
+
+To typecheck our route name and params, the first thing we need to do is to create an object type with mappings for route names to the params of the route. For example, say we have a route called `Profile` in our root navigator which should have a param `userId`:
```tsx
type RootStackParamList = {
@@ -28,7 +170,7 @@ type RootStackParamList = {
Specifying `undefined` means that the route doesn't have params. A union type with `undefined` (e.g. `SomeType | undefined`) means that params are optional.
-After we have defined the mappings, we need to tell our navigator to use it. To do that, we can pass it as a generic to the `createXNavigator` functions:
+After we have defined the mapping, we need to tell our navigator to use it. To do that, we can pass it as a generic to the [`createXNavigator`](static-configuration.md) functions:
```tsx
import { createStackNavigator } from '@react-navigation/stack';
@@ -50,17 +192,23 @@ And then we can use it:
```
-This will provide type checking and intelliSense for props of the `Navigator` and `Screen` components.
+This will provide type checking and intelliSense for props of the [`Navigator`](navigator.md) and [`Screen`](screen.md) components.
:::note
-The type containing the mappings must be a type alias (e.g. `type RootStackParamList = { ... }`). It cannot be an interface (e.g. `interface RootStackParamList { ... }`). It also shouldn't extend `ParamListBase` (e.g. `interface RootStackParamList extends ParamListBase { ... }`). Doing so will result in incorrect type checking where it allows you to pass incorrect route names.
+The type containing the mapping must be a type alias (e.g. `type RootStackParamList = { ... }`). It cannot be an interface (e.g. `interface RootStackParamList { ... }`). It also shouldn't extend `ParamListBase` (e.g. `interface RootStackParamList extends ParamListBase { ... }`). Doing so will result in incorrect type checking which allows you to pass incorrect route names.
:::
-### Type checking screens
+If you have an [`id`](./navigator.md#id) prop for your navigator, you will also need to pass it as a generic:
+
+```tsx
+const RootStack = createStackNavigator();
+```
+
+## Type checking screens
-To type check our screens, we need to annotate the `navigation` and the `route` props received by a screen. The navigator packages in React Navigation export generic types to define types for both the `navigation` and `route` props from the corresponding navigator.
+To typecheck our screens, we need to annotate the `navigation` and the `route` props received by a screen. The navigator packages in React Navigation export generic types to define types for both the `navigation` and `route` props from the corresponding navigator.
For example, you can use `NativeStackScreenProps` for the Native Stack Navigator.
@@ -82,15 +230,15 @@ The type takes 3 generics:
- The name of the route the screen belongs to
- The ID of the navigator (optional)
-If you have an `id` prop for your navigator, you can do:
+If you have an [`id`](./navigator.md#id) prop for your navigator, you can do:
```ts
type Props = NativeStackScreenProps;
```
-This allows us to type check route names and params which you're navigating using `navigate`, `push` etc. The name of the current route is necessary to type check the params in `route.params` and when you call `setParams`.
+This allows us to type check route names and params which you're navigating using [`navigate`](navigation-object.md#navigate), [`push`](stack-actions.md#push) etc. The name of the current route is necessary to type check the params in `route.params` and when you call [`setParams`](navigation-actions#setparams) or [`replaceParams`](navigation-actions#replaceparams).
-Similarly, you can import `StackScreenProps` for `@react-navigation/stack`, `DrawerScreenProps` from `@react-navigation/drawer`, `BottomTabScreenProps` from `@react-navigation/bottom-tabs` and so on.
+Similarly, you can import `StackScreenProps` from [`@react-navigation/stack`](stack-navigator.md), `DrawerScreenProps` from [`@react-navigation/drawer`](drawer-navigator.md), `BottomTabScreenProps` from [`@react-navigation/bottom-tabs`](bottom-tab-navigator.md) and so on.
Then you can use the `Props` type you defined above to annotate your component.
@@ -133,7 +281,7 @@ type ProfileScreenNavigationProp = NativeStackNavigationProp<
>;
```
-Similarly, you can import `StackNavigationProp` from `@react-navigation/stack`, `DrawerNavigationProp` from `@react-navigation/drawer`, `BottomTabNavigationProp` from `@react-navigation/bottom-tabs` etc.
+Similarly, you can import `StackNavigationProp` from [`@react-navigation/stack`](stack-navigator.md), `DrawerNavigationProp` from [`@react-navigation/drawer`](drawer-navigator.md), `BottomTabNavigationProp` from [`@react-navigation/bottom-tabs`](bottom-tab-navigator.md) etc.
To get the type for the `route` object, we need to use the `RouteProp` type from `@react-navigation/native`:
@@ -143,11 +291,11 @@ import type { RouteProp } from '@react-navigation/native';
type ProfileScreenRouteProp = RouteProp;
```
-We recommend creating a separate `types.tsx` file where you keep the types and import them in your component files instead of repeating them in each file.
+We recommend creating a separate file: `types.tsx` - where you keep the types and import from there in your component files instead of repeating them in each file.
-### Nesting navigators
+## Nesting navigators
-#### Type checking screens and params in nested navigator
+### Type checking screens and params in nested navigator
You can [navigate to a screen in a nested navigator](nesting-navigators.md#navigating-to-a-screen-in-a-nested-navigator) by passing `screen` and `params` properties for the nested screen:
@@ -169,9 +317,11 @@ type TabParamList = {
};
```
-#### Combining navigation props
+### Combining navigation props
-When you nest navigators, the navigation prop of the screen is a combination of multiple navigation props. For example, if we have a tab inside a stack, the `navigation` prop will have both `jumpTo` (from the tab navigator) and `push` (from the stack navigator). To make it easier to combine types from multiple navigators, you can use the `CompositeScreenProps` type:
+When you nest navigators, the navigation prop of the screen is a combination of multiple navigation props. For example, if we have a tab inside a stack, the `navigation` prop will have both [`jumpTo`](tab-actions.md#jumpto) (from the tab navigator) and [`push`](stack-actions.md#push) (from the stack navigator). To make it easier to combine types from multiple navigators, you can use the `CompositeScreenProps` type.
+
+For example, if we have a `Profile` in a navigator, nested inside `Account` screen of a stack navigator, we can combine the types as follows:
```ts
import type { CompositeScreenProps } from '@react-navigation/native';
@@ -180,20 +330,23 @@ import type { StackScreenProps } from '@react-navigation/stack';
type ProfileScreenProps = CompositeScreenProps<
BottomTabScreenProps,
- StackScreenProps
+ StackScreenProps
>;
```
-The `CompositeScreenProps` type takes 2 parameters, first parameter is the type of props for the primary navigation (type for the navigator that owns this screen, in our case the tab navigator which contains the `Profile` screen) and second parameter is the type of props for secondary navigation (type for a parent navigator). The primary type should always have the screen's route name as its second parameter.
+The `CompositeScreenProps` type takes 2 parameters:
+
+- The first parameter is the type for the navigator that owns this screen, in our case the tab navigator which contains the `Profile` screen
+- The second parameter is the type of props for a parent navigator, in our case the stack navigator which contains the `Account` screen
-For multiple parent navigators, this secondary type should be nested:
+For multiple parent navigators, this second parameter can nest another `CompositeScreenProps`:
```ts
type ProfileScreenProps = CompositeScreenProps<
BottomTabScreenProps,
CompositeScreenProps<
- StackScreenProps,
- DrawerScreenProps
+ StackScreenProps,
+ DrawerScreenProps
>
>;
```
@@ -207,11 +360,11 @@ import type { StackNavigationProp } from '@react-navigation/stack';
type ProfileScreenNavigationProp = CompositeNavigationProp<
BottomTabNavigationProp,
- StackNavigationProp
+ StackNavigationProp
>;
```
-### Annotating `useNavigation`
+## Annotating `useNavigation`
:::danger
@@ -220,13 +373,13 @@ Prefer [specifying a default type](#specifying-default-types-for-usenavigation-l
:::
-To annotate the `navigation` object that we get from `useNavigation`, we can use a type parameter:
+To annotate the `navigation` object that we get from [`useNavigation`](use-navigation.md), we can use a type parameter:
```ts
const navigation = useNavigation();
```
-### Annotating `useRoute`
+## Annotating `useRoute`
:::danger
@@ -235,13 +388,13 @@ Prefer using the [`route` object](route-object.md) from the screen component's p
:::
-To annotate the `route` object that we get from `useRoute`, we can use a type parameter:
+To annotate the `route` object that we get from [`useRoute`](use-route.md), we can use a type parameter:
```ts
const route = useRoute();
```
-### Annotating `options` and `screenOptions`
+## Annotating `options` and `screenOptions`
When you pass the `options` to a `Screen` or `screenOptions` prop to a `Navigator` component, they are already type-checked and you don't need to do anything special. However, sometimes you might want to extract the options to a separate object, and you might want to annotate it.
@@ -257,9 +410,22 @@ const options: StackNavigationOptions = {
Similarly, you can import `DrawerNavigationOptions` from `@react-navigation/drawer`, `BottomTabNavigationOptions` from `@react-navigation/bottom-tabs` etc.
-When using the function form of `options` and `screenOptions`, you can annotate the arguments with the same type you used to annotate the `navigation` and `route` objects from the [Type checking screens](#type-checking-screens) section.
+When using the function form of `options` and `screenOptions`, you can annotate the arguments with a type exported from the navigator, e.g. `StackOptionsArgs` for `@react-navigation/stack`, `DrawerOptionsArgs` for `@react-navigation/drawer`, `BottomTabOptionsArgs` for `@react-navigation/bottom-tabs` etc.:
+
+```ts
+import type {
+ StackNavigationOptions,
+ StackOptionsArgs,
+} from '@react-navigation/stack';
+
+const options = ({ route }: StackOptionsArgs): StackNavigationOptions => {
+ return {
+ headerTitle: route.name,
+ };
+};
+```
-### Annotating `ref` on `NavigationContainer`
+## Annotating `ref` on `NavigationContainer`
If you use the `createNavigationContainerRef()` method to create the ref, you can annotate it to type-check navigation actions:
@@ -305,7 +471,7 @@ const navigationRef =
React.createRef>();
```
-### Specifying default types for `useNavigation`, `Link`, `ref` etc
+## Specifying default types for `useNavigation`, `Link`, `ref` etc
Instead of manually annotating these APIs, you can specify a global type for your root navigator which will be used as the default type.
@@ -321,13 +487,13 @@ declare global {
The `RootParamList` interface lets React Navigation know about the params accepted by your root navigator. Here we extend the type `RootStackParamList` because that's the type of params for our stack navigator at the root. The name of this type isn't important.
-Specifying this type is important if you heavily use `useNavigation`, `Link` etc. in your app since it'll ensure type-safety. It will also make sure that you have correct nesting on the `linking` prop.
+Specifying this type is important if you heavily use [`useNavigation`](use-navigation.md), [`Link`](link.md) etc. in your app since it'll ensure type-safety. It will also make sure that you have correct nesting on the [`linking`](navigation-container.md#linking) prop.
-### Organizing types
+## Organizing types
When writing types for React Navigation, there are a couple of things we recommend to keep things organized.
-1. It's good to create a separate files (e.g. `navigation/types.tsx`) which contains the types related to React Navigation.
+1. It's good to create a separate file (e.g. `navigation/types.tsx`) that contains the types related to React Navigation.
2. Instead of using `CompositeNavigationProp` directly in your components, it's better to create a helper type that you can reuse.
3. Specifying a global type for your root navigator would avoid manual annotations in many places.
@@ -358,7 +524,7 @@ export type HomeTabParamList = {
export type HomeTabScreenProps =
CompositeScreenProps<
BottomTabScreenProps,
- RootStackScreenProps
+ RootStackScreenProps
>;
declare global {
@@ -378,7 +544,7 @@ function PopularScreen({ navigation, route }: HomeTabScreenProps<'Popular'>) {
}
```
-If you're using hooks such as `useRoute`, you can write:
+If you're using hooks such as [`useRoute`](use-route.md), you can write:
```ts
import type { HomeTabScreenProps } from './navigation/types';
@@ -389,3 +555,6 @@ function PopularScreen() {
// ...
}
```
+
+
+
diff --git a/versioned_docs/version-7.x/upgrading-from-6.x.md b/versioned_docs/version-7.x/upgrading-from-6.x.md
index 15cc60b8a87..fd5c971cedf 100755
--- a/versioned_docs/version-7.x/upgrading-from-6.x.md
+++ b/versioned_docs/version-7.x/upgrading-from-6.x.md
@@ -11,12 +11,14 @@ This guides lists all the breaking changes and new features in React Navigation
## Minimum Requirements
- `react-native` >= 0.72.0
-- `expo` >= 49 (if you use Expo)
+- `expo` >= 52 (if you use [Expo Go](https://expo.dev/go))
- `typescript` >= 5.0.0 (if you use TypeScript)
## Breaking changes
-### The `navigate` method no longer navigates to screen in a nested child navigator
+### Changes to the `navigate` action
+
+#### The `navigate` method no longer navigates to screen in a nested child navigator
Due to backward compatibility reasons, React Navigation 5 and 6 support navigating to a screen in a nested child navigator with `navigation.navigate(ScreenName)` syntax. But this is problematic:
@@ -25,21 +27,23 @@ Due to backward compatibility reasons, React Navigation 5 and 6 support navigati
Due to these issues, we have a special API to navigate to a nested screen (`navigation.navigate(ParentScreenName, { screen: ScreenName })`).
-From these release, this is no longer the default behavior. If you're relying on this behavior in your app, you can pass the `navigationInChildEnabled` prop to `NavigationContainer` to keep the behavior until you are able to migrate:
+From these release, this is no longer the default behavior. If you're relying on this behavior in your app, you can pass the [`navigationInChildEnabled`](navigation-container.md#navigationinchildenabled) prop to `NavigationContainer` to keep the behavior until you are able to migrate:
-```js
+```jsx
{/* ... */}
```
The `navigationInChildEnabled` prop will be removed in the next major.
-### The `navigate` method no longer goes back, use `popTo` instead
+See [`navigate`](navigation-object.md#navigate) for updated usage.
+
+#### The `navigate` method no longer goes back, use `popTo` instead
Previously, `navigate` method navigated back if the screen already exists in the stack. We have seen many people get confused by this behavior.
To avoid this confusion, we have removed the going back behavior from `navigate` and added a [new method `popTo`](stack-actions.md#popto) to explicitly go back to a specific screen in the stack:
-```diff
+```diff lang=js
- navigation.navigate('PreviousScreen', { foo: 42 });
+ navigation.popTo('PreviousScreen', { foo: 42 });
```
@@ -49,18 +53,25 @@ The methods now behave as follows:
- `navigate(screenName)` will stay on the current screen if the screen is already focused, otherwise push a new screen to the stack.
- `popTo(screenName)` will go back to the screen if it exists in the stack, otherwise pop the current screen and add this screen to the stack.
-To achieve a behavior similar to before with `navigate`, you can use the [`getId`](screen.md#getid) prop in which case it'll go to the screen with the matching ID and push or pop screens accordingly.
+See [`popTo`](stack-actions.md#popto) for more details.
-To help with the migration, we have added a new method called `navigateDeprecated` which will behave like the old `navigate` method. You can replace your current `navigate` calls with `navigateDeprecated` to gradually migrate to the new behavior:
+To achieve a behavior similar to before with `navigate`, you can use specify `pop: true` in the options:
-```diff
+```diff lang=js
+- navigation.navigate('PreviousScreen', { foo: 42 });
++ navigation.navigate('PreviousScreen', { foo: 42 }, { pop: true });
+```
+
+To help with the migration, we have added a new method called `navigateDeprecated` which will behave like the old `navigate` method. You can replace your current `navigate` calls with [`navigateDeprecated`](navigation-object.md#navigatedeprecated) to gradually migrate to the new behavior:
+
+```diff lang=js
- navigation.navigate('SomeScreen');
+ navigation.navigateDeprecated('SomeScreen');
```
The `navigateDeprecated` method will be removed in the next major.
-### The `navigate` method no longer accepts a `key` option
+#### The `navigate` method no longer accepts a `key` option
Previously, you could specify a route `key` to navigate to, e.g.:
@@ -74,12 +85,15 @@ It's problematic since:
- None of the other actions support such usage.
- Specifying a `key` is not type-safe, making it easy to cause bugs.
-In React Navigation 5, we added the [`getId`](screen.md#getid) prop which can be used for similar use cases - and gives users full control since they provide the ID and it's not autogenerated by the
-library.
+In React Navigation 5, we added the [`getId`](screen.md#id) prop which can be used for similar use cases - and gives users full control since they provide the ID and it's not autogenerated by the library.
So the `key` option is now being removed from the `navigate` action.
-### The `onReady` callback on `NavigationContainer` now fires only when there are navigators rendered
+See [`navigate`](navigation-object.md#navigate) for updated usage.
+
+### Changes to `NavigationContainer`
+
+#### The `onReady` callback on `NavigationContainer` now fires only when there are navigators rendered
Previously, the `onReady` prop and `navigationRef.isReady()` worked slightly differently:
@@ -92,7 +106,9 @@ This changes `onReady` to work similar to `navigationRef.isReady()`. The `onRead
This change is not breaking for most users, so you may not need to do anything.
-### The `independent` prop on `NavigationContainer` is removed in favor of `NavigationIndependentTree` component
+See [`onReady`](navigation-container.md#onready) for usage.
+
+#### The `independent` prop on `NavigationContainer` is removed in favor of `NavigationIndependentTree` component
The `independent` prop on `NavigationContainer` was added to support rendering navigators in a separate tree from the rest of the app. This is useful for use cases such as miniapps.
@@ -103,37 +119,76 @@ However, there are issues with this approach:
So we've removed this prop instead of a `NavigationIndependentTree` component which you can use to wrap the navigation container:
-```diff
--
-- {/* ... */}
--
-+
-+
-+ {/* ... */}
-+
-+
+```diff lang=jsx
+-
+- {/* ... */}
+-
++
++
++ {/* ... */}
++
++
```
This way, the responsibility no longer lies on the miniapp developer, but on the parent app. It's also harder for beginners to accidentally add this.
-### The `theme` prop now accepts a `fonts` property
+See [Independent navigation containers](navigation-container.md#independent-navigation-containers) for usage.
+
+#### The `theme` prop now accepts a `fonts` property
Previously, the `theme` prop on `NavigationContainer` accepted a `colors` property to customize the colors used by various UI elements from React Navigation. We have now added a `fonts` property to customize the fonts as well. If you are passing a custom theme in the `theme` prop, you'll need to update it to include the `fonts` property.
-```diff
+```diff lang=js
import { DefaultTheme } from '@react-navigation/native';
const theme = {
colors: {
// ...
},
-+ fonts: DefaultTheme.fonts,
++ fonts: DefaultTheme.fonts,
};
```
If you want to customize the fonts, see [the themes guide](themes.md) for more details.
-### The `Link` component and `useLinkProps` hook now use screen names instead of paths
+#### The navigation state is frozen in development mode
+
+The navigation state is now frozen in development mode to prevent accidental mutations. This includes the state object and all the nested objects such as `route` object etc. If you're mutating the navigation state directly, you may get an error like `Cannot assign to read only property 'key' of object`.
+
+Note that React Navigation relies on the immutability of the navigation state to detect changes and update the UI. Mutating the navigation state directly can cause issues and was never supported. So if you're mutating the navigation state directly, you'll need to use a different approach.
+
+### Changes to linking
+
+#### Encoding of params in path position is now more relaxed
+
+Previously, params were always URL encoded with `encodeURIComponent` regardless of their position (e.g. query position such as `?user=jane` or path position such as `/users/jane`) when generating a link for a screen (e.g. URL on the Web). This made it hard to use special characters in the params.
+
+Now, only the params in the query position are URL encoded. For the params in the path position, we only encode the characters that are not allowed in the path position.
+
+With this change, it's easier to use special characters such as `@` in the path. For example, to have a URL such as `profile/@username`, you can use the following in the linking config:
+
+```js
+const config = {
+ prefixes: ['https://mysite.com'],
+ config: {
+ screens: {
+ Profile: {
+ path: 'profile/:username',
+ parse: {
+ username: (username) => username.replace(/^@/, ''),
+ },
+ stringify: {
+ username: (username) => `@${username}`,
+ },
+ },
+ },
+ },
+};
+```
+
+See [Configuring links](configuring-links.md) for usage of the linking config.
+
+#### The `Link` component and `useLinkProps` hook now use screen names instead of paths
Previously, the `Link` component and `useLinkProps` hook were designed to work with path strings via the `to` prop. But it had few issues:
@@ -142,21 +197,23 @@ Previously, the `Link` component and `useLinkProps` hook were designed to work w
Now, instead of the `to` prop that took a path string, they now accept `screen` and `params` props, as well as an optional `href` prop to use instead of the generated path:
-```diff
-- Go to Details
-+ Go to Details
+```diff lang=jsx
+- Go to Details
++ Go to Details
```
or
-```diff
--const props = useLinkProps({ to: '/details?foo=42' });
-+const props = useLinkProps({ screen: 'Details', params: { foo: 42 } });
+```diff lang=js
+- const props = useLinkProps({ to: '/details?foo=42' });
++ const props = useLinkProps({ screen: 'Details', params: { foo: 42 } });
```
With this change, you'd now have full type-safety when using the `Link` component given that you have [configured the global type](typescript.md#specifying-default-types-for-usenavigation-link-ref-etc).
-### The `useLinkBuilder` hooks now returns an object instead of a function
+See [`Link`](link.md) and [`useLinkProps`](use-link-props.md) for usage.
+
+#### The `useLinkBuilder` hooks now returns an object instead of a function
Previously, the `useLinkBuilder` hooks returned a function to build a `href` for a screen - which is primarily useful for building custom navigators. Now, it returns an object with `buildHref` and `buildAction` methods:
@@ -171,7 +228,239 @@ The `buildHref` method acts the same as the previously returned function. The ne
Note that this hook is intended to be primarily used by custom navigators and not by end users. For end users, the `Link` component and `useLinkProps` are the recommended way to navigate.
-### The flipper devtools plugin is now removed
+See [`useLinkBuilder`](use-link-builder.md) for usage.
+
+### Changes to navigators
+
+#### Screens pushed on top of modals are now shown as modals in the Stack and Native Stack navigators
+
+Previously, screens pushed on top of modals were shown as regular screens in the Stack and Native Stack navigators. This often caused glitchy animation on Stack Navigator and appeared behind the modal on Native Stack Navigator. This can be especially confusing if the user came to the screen from a deep link.
+
+Now, screens pushed on top of modals are automatically shown as modals to avoid these issues. This behavior can be disabled by explicitly setting the `presentation` option to `card`:
+
+```jsx
+
+```
+
+See [Stack Navigator](stack-navigator.md#presentation) and [Native Stack Navigator](native-stack-navigator.md#presentation) docs for usage.
+
+#### `headerBackTitleVisible` is removed in favor of `headerBackButtonDisplayMode` in Stack and Native Stack navigators
+
+Previously, `headerBackTitleVisible` could be used to control whether the back button title is shown in the header. It's now removed in favor of `headerBackButtonDisplayMode` which provides more flexibility.
+
+The previous behavior can be achieved by setting `headerBackButtonDisplayMode` to `default` and `minimal` for showing and hiding the back button title respectively:
+
+```diff lang=js
+
+```
+
+#### `animationEnabled` option is removed in favor of `animation` option in Stack Navigator
+
+Previously, `animationEnabled: false` was used to disable the animation for the screen transition in Stack Navigator.
+
+There's now a new `animation` prop to configure animations similar to the Native Stack. So you can now use `animation: 'none'` to disable the animation instead:
+
+```diff lang=js
+
+```
+
+See [Stack Navigator animation](stack-navigator.md#animations) for usage.
+
+#### `customAnimationOnGesture` is renamed to `animationMatchesGesture` in Native Stack Navigator
+
+The `customAnimationOnGesture` option in Native Stack Navigator is renamed to `animationMatchesGesture` to better reflect its purpose. If you are using `customAnimationOnGesture` in your project, you can rename it to `animationMatchesGesture`:
+
+```diff lang=js
+-
++
+```
+
+See [Native Stack Navigator](native-stack-navigator.md#animationmatchesgesture) for usage.
+
+#### `statusBarColor` is renamed to `statusBarBackgroundColor` in Native Stack Navigator
+
+The `statusBarColor` option in Native Stack Navigator is renamed to `statusBarBackgroundColor` to better reflect its purpose. If you are using `statusBarColor` in your project, you can rename it to `statusBarBackgroundColor`:
+
+```diff lang=js
+-
++
+```
+
+See [Native Stack Navigator](native-stack-navigator.md#statusbarbackgroundcolor) for usage.
+
+#### Native Stack now requires `react-native-screens` 4
+
+`@react-navigation/native-stack` now requires `react-native-screens` 4 and will break when using an earlier version. If you are using Native Stack Navigator in your project, make sure to upgrade `react-native-screens` to version 4.
+
+See [Native Stack Navigator](native-stack-navigator.md) for usage.
+
+#### Material Top Tab Navigator no longer requires installing `react-native-tab-view`
+
+Previously, `@react-navigation/material-top-tabs` required installing `react-native-tab-view` as a dependency in the project. We have now moved this package to the React Navigation monorepo and able to coordinate the releases together, so it's no longer necessary to install it separately.
+
+If you use `@react-navigation/material-top-tabs` and don't use `react-native-tab-view` anywhere else in your project, you can remove it from your dependencies after upgrading.
+
+If you need to enforce a specific version of `react-native-tab-view` for some reason, we recommend using [Yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) or [npm overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) to do so.
+
+See [Material Top Tab Navigator](material-top-tab-navigator.md) for usage.
+
+#### The `unmountOnBlur` option is removed in favor of `popToTopOnBlur` in Bottom Tab Navigator and Drawer Navigator
+
+In many cases, the desired behavior is to return to the first screen of the stack nested in a tab or drawer navigator after it's unfocused. Previously, the `unmountOnBlur` option was used to achieve this behavior. However, it had some issues:
+
+- It destroyed the local state of the screen in the stack.
+- It was slow to remount the nested navigator on tab navigation.
+
+The `popToTopOnBlur` option provides an alternative approach - it pops the screens on a nested stack to go back to the first screen in the stack and doesn't have the above issues.
+
+See [Bottom Tab Navigator](bottom-tab-navigator.md#poptotoponblur) and [Drawer Navigator](drawer-navigator.md#poptotoponblur) docs for usage.
+
+It's still possible to achieve the old behavior of `unmountOnBlur` by using the [`useIsFocused`](use-is-focused.md) hook in the screen:
+
+```js
+const isFocused = useIsFocused();
+
+if (!isFocused) {
+ return null;
+}
+```
+
+This could also be combined with the new [layout props](#new-layout-props) to specify it at the screen configuration level to make the migration easier.
+
+To achieve this, define a component that uses the `useIsFocused` hook to conditionally render its children:
+
+```js
+function UnmountOnBlur({ children }) {
+ const isFocused = useIsFocused();
+
+ if (!isFocused) {
+ return null;
+ }
+
+ return children;
+}
+```
+
+Then use the component in `layout` prop of the screen:
+
+```diff lang=js
+ {children} }
+ options={{
+- unmountOnBlur: true,
+ }}
+/>
+```
+
+Or `screenLayout` prop of the navigator:
+
+```diff lang=js
+ {children} }
+ screenOptions={{
+- unmountOnBlur: true,
+ }}
+>
+```
+
+#### The `tabBarTestID` option is renamed to `tabBarButtonTestID` in Bottom Tab Navigator and Material Top Tab Navigator
+
+The `tabBarTestID` option in `@react-navigation/bottom-tabs` and `@react-navigation/material-top-tabs` is renamed to `tabBarButtonTestID` to better reflect its purpose. If you are using `tabBarTestID` in your project, you can rename it to `tabBarButtonTestID`:
+
+```diff lang=js
+-
++
+```
+
+See [Bottom Tab Navigator](bottom-tab-navigator.md#tabbarbuttontestid) and [Material Top Tab Navigator](material-top-tab-navigator.md#tabbarbuttontestid) docs for usage.
+
+#### The `sceneContainerStyle` prop and option are removed from Bottom Tab Navigator, Material Top Tab Navigator and Drawer Navigator in favor of `sceneStyle`
+
+Previously, the Bottom Tab Navigator and Material Top Tab Navigator accepted a `sceneContainerStyle` prop to style the container of the scene. This was inflexible as it didn't allow different styles for different screens. Now, the `sceneStyle` option is added to these navigators to style individual screens.
+
+Similarly, the `sceneContainerStyle` option in Drawer Navigator is renamed to `sceneStyle` for consistency.
+
+If you are using `sceneContainerStyle` prop, you can pass `sceneStyle` in `screenOptions` instead to keep the same behavior:
+
+```diff lang=js
+-
++
+```
+
+#### Drawer Navigator now requires Reanimated 2 or 3 on native platforms
+
+Previously, `@react-navigation/drawer` supported both Reanimated 1 and Reanimated 2 APIs with the `useLegacyImplementation` option. This is now no longer supported and the `useLegacyImplementation` option is removed.
+
+If you are using Reanimated 1 in your project, you'll need to upgrade to Reanimated 2 or 3 to use `@react-navigation/drawer`.
+
+If you're using Drawer Navigator on the Web, it'll now use CSS transitions instead of Reanimated for a smaller bundle size.
+
+See [Drawer Navigator](drawer-navigator.md) for usage.
+
+### Changes to elements
+
+#### `labelVisible` is removed in favor of `displayMode` in `headerLeft` and `HeaderBackButton` elements
+
+Previously, `labelVisible` could be used to control whether the back button title is shown in the header. It's now removed in favor of `displayMode` which provides more flexibility.
+
+The new possible values are:
+
+- `default`: Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
+- `generic`: Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon). iOS >= 14 only, falls back to "default" on older iOS versions.
+- `minimal`: Always displays only the icon without a title.
+
+The previous behavior can be achieved by setting `displayMode` to `default` or `generic` for showing and `minimal` for hiding the back button title respectively:
+
+```diff lang=js
+
+```
+
+### Deprecations and removals
+
+#### Material Bottom Tab Navigator now lives in `react-native-paper` package
+
+The `@react-navigation/material-bottom-tabs` package provided React Navigation integration for `react-native-paper`'s `BottomNavigation` component. To make it easier to keep it updated with the changes in `react-native-paper`, we have now moved it to the `react-native-paper` package.
+
+If you are using `@react-navigation/material-bottom-tabs` in your project, you can remove it from your dependencies and change the imports to `react-native-paper/react-navigation` instead:
+
+```diff lang=js
+- import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
++ import { createMaterialBottomTabNavigator } from 'react-native-paper/react-navigation';
+```
+
+See [Material Bottom Tab Navigator](https://callstack.github.io/react-native-paper/docs/guides/bottom-navigation/) for usage.
+
+Alternatively, you can use the [`BottomNavigation.Bar`](https://callstack.github.io/react-native-paper/docs/components/BottomNavigation/BottomNavigationBar) component as a custom tab bar with `@react-navigation/bottom-tabs`.
+
+For any issues related to the Material Bottom Tab Navigator or `BottomNavigation.Bar`, please open them in the [react-native-paper repository](https://github.com/callstack/react-native-paper) instead of the React Navigation repository.
+
+#### The flipper devtools plugin is now removed
Previously, we added a Flipper plugin for React Navigation to make debugging navigation easier. However, it has added significant maintenance overhead for us. The Flipper team hasn't been focused on React Native recently, so the overall experience of using Flipper with React Native has been poor.
@@ -181,11 +470,18 @@ Previously, we added a Flipper plugin for React Navigation to make debugging nav
Since the React Native team migrating away from Flipper, it doesn't make much sense for us to spend additional resources to keep supporting it. So we've removed the Flipper plugin from `@react-navigation/devtools`.
-### Various deprecated APIs are removed
+Alternatively, you can use the following developer tools:
+
+- [Logger](devtools.md#uselogger)
+- [Integration for Redux DevTools Extension](devtools.md#usereduxdevtoolsextension)
+- [Devtools plugin for Expo](https://docs.expo.dev/debugging/devtools-plugins/#react-navigation) if you are using [Expo](https://expo.dev).
+
+#### Various deprecated APIs are removed
We have removed all of the previously deprecated APIs. These APIs were deprecated in React Navigation 6 and showed a warning when used. So make sure that you have addressed all the warnings before upgrading.
-Here is the full list of removed APIs:
+
+Full list of removed APIs
- `@react-navigation/stack`
- Removed `mode` prop - use `presentation` option instead
@@ -203,7 +499,7 @@ Here is the full list of removed APIs:
- `minSwipeDistance` - use `swipeMinDistance` option instead
- `overlayColor` - use `overlayColor` option instead
- `statusBarAnimation` - use `drawerStatusBarAnimation` option instead
- - `gestureHandlerProps` - use `gestureHandlerProps` option instead
+ - `gestureHandlerProps` - use `configureGestureHandler` option instead
- `@react-navigation/bottom-tabs`
- Removed `lazy` prop - use `lazy` option instead
- Removed `tabBarOptions` prop which contained following options:
@@ -224,91 +520,504 @@ Here is the full list of removed APIs:
- Removed `lazy` prop - use `lazy` option instead
- Removed `lazyPlaceholder` prop - use `lazyPlaceholder` option instead
- Removed `lazyPreloadDistance` prop - use `lazyPreloadDistance` option instead
- - Removed `tabBarOptions` prop which contained following options:
- - `renderBadge` - use `tabBarBadge` option instead
- - `renderIndicator` - use `tabBarIndicator` option instead
- - `activeTintColor` - use `tabBarActiveTintColor` option instead
- - `inactiveTintColor` - use `tabBarInactiveTintColor` option instead
- - `pressColor` - use `tabBarPressColor` option instead
- - `pressOpacity` - use `tabBarPressOpacity` option instead
- - `showLabel` - use `tabBarShowLabel` option instead
- - `showIcon` - use `tabBarShowIcon` option instead
- - `allowFontScaling` - use `tabBarAllowFontScaling` option instead
- - `bounces` - use `tabBarBounces` option instead
- - `scrollEnabled` - use `tabBarScrollEnabled` option instead
- - `iconStyle` - use `tabBarIconStyle` option instead
- - `labelStyle` - use `tabBarLabelStyle` option instead
- - `tabStyle` - use `tabBarItemStyle` option instead
- - `indicatorStyle` - use `tabBarIndicatorStyle` option instead
- - `indicatorContainerStyle` - use `tabBarIndicatorContainerStyle` option instead
- - `contentContainerStyle` - use `tabBarContentContainerStyle` option instead
- - `style` - use `tabBarStyle` option instead
+ - Removed `tabBarOptions` prop which contained following options: - `renderBadge` - use `tabBarBadge` option instead - `renderIndicator` - use `tabBarIndicator` option instead - `activeTintColor` - use `tabBarActiveTintColor` option instead - `inactiveTintColor` - use `tabBarInactiveTintColor` option instead - `pressColor` - use `tabBarPressColor` option instead - `pressOpacity` - use `tabBarPressOpacity` option instead - `showLabel` - use `tabBarShowLabel` option instead - `showIcon` - use `tabBarShowIcon` option instead - `allowFontScaling` - use `tabBarAllowFontScaling` option instead - `bounces` - use `tabBarBounces` option instead - `scrollEnabled` - use `tabBarScrollEnabled` option instead - `iconStyle` - use `tabBarIconStyle` option instead - `labelStyle` - use `tabBarLabelStyle` option instead - `tabStyle` - use `tabBarItemStyle` option instead - `indicatorStyle` - use `tabBarIndicatorStyle` option instead - `indicatorContainerStyle` - use `tabBarIndicatorContainerStyle` option instead - `contentContainerStyle` - use `tabBarContentContainerStyle` option instead - `style` - use `tabBarStyle` option instead
-### `customAnimationOnGesture` is renamed to `animationMatchesGesture` in Native Stack Navigator
+
-TODO
+### Miscellaneous
-### Material Top Tab Navigator no longers requires installing `react-native-tab-view`
+#### Various UI elements now follow Material Design 3 guidelines
-Previously, `@react-navigation/material-top-tabs` required installing `react-native-tab-view` as a dependency in the project. We have now moved this package to the React Navigation monorepo and able to coordinate the releases together, so it's no longer necessary to install it separately.
+Previously, the UI elements in React Navigation such as the header on platforms other than iOS, drawer, material top tabs etc. were following the Material Design 2 guidelines. We have now updated them to follow the Material Design 3 guidelines.
-If you use `@react-navigation/material-top-tabs` and don't use `react-native-tab-view` anywhere else in your project, you can remove it from your dependencies after upgrading.
+#### React Native Tab View now has a new API to specify various options
-If you need to enforce a specific version of `react-native-tab-view` for some reason, we recommend using [Yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) or [npm overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) to do so.
+The API for the `TabView` and `TabBar` component in `react-native-tab-view` has been revamped.
-### Material Bottom Tab Navigator now lives in `react-native-paper` package
+Some of props accepted by the `TabBar` have now been replaced with `commonOptions` and `options` props on `TabView`:
-The `@react-navigation/material-bottom-tabs` package provided React Navigation integration for `react-native-paper`'s `BottomNavigation` component. To make it easier to keep it updated with the changes in `react-native-paper`, we have now moved it to the `react-native-paper` package.
+- `getLabelText` -> `labelText`
+- `getAccessible` -> `accessible`
+- `getAccessibilityLabel` -> `accessibilityLabel`
+- `getTestID` -> `testID`
+- `renderIcon` -> `icon`
+- `renderLabel` -> `label`
+- `renderBadge` -> `badge`
+- `labelStyle`
+- `sceneContainerStyle` -> `sceneStyle`
-If you are using `@react-navigation/material-bottom-tabs` in your project, you can remove it from your dependencies and change the imports to `react-native-paper/react-navigation` instead:
+To keep the same behavior when updating your existing code, move these props to `commonOptions` prop on `TabView`:
-```diff
-- import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
-+ import { createMaterialBottomTabNavigator } from 'react-native-paper/react-navigation';
+```diff lang=js
+ (
+-
++
+ )}
++ commonOptions={{
++ label: renderLabel,
++ labelStyle,
++ }}
+/>
+```
+
+The options can also be customized individually for each tab by passing an object to the `options` prop with the `route.key` as the key and the options as the value:
+
+```js
+ (
+
+ ),
+ }}
+ options={{
+ albums: {
+ labelText: 'Albums',
+ },
+ profile: {
+ labelText: 'Profile',
+ },
+ }}
+/>
```
-### The `tabBarTestID` option is renamed to `tabBarButtonTestID` in Bottom Tab Navigator
+When using a custom tab bar, it will receive the `options` in the arguments.
+
+The new API will make it easier for us to improve re-rendering performance of the tab bar items in the library.
+
+See [React Native Tab View](tab-view.md#options) for usage.
+
+#### Custom navigators now require more type information
+
+Custom navigators now require more type information to work correctly so that we can provide better type-checking and autocompletion in TypeScript when using the navigator.
+
+```diff lang=js
+- export const createMyNavigator = createNavigatorFactory<
+- MyNavigationState,
+- MyNavigationOptions,
+- MyNavigationEventMap,
+- typeof MyNavigator
+- >(MyNavigator);
++ export function createMyNavigator<
++ const ParamList extends ParamListBase,
++ const NavigatorID extends string | undefined = undefined,
++ const TypeBag extends NavigatorTypeBagBase = {
++ ParamList: ParamList;
++ NavigatorID: NavigatorID;
++ State: TabNavigationState;
++ ScreenOptions: TabNavigationOptions;
++ EventMap: TabNavigationEventMap;
++ NavigationList: {
++ [RouteName in keyof ParamList]: TabNavigationProp<
++ ParamList,
++ RouteName,
++ NavigatorID
++ >;
++ };
++ Navigator: typeof TabNavigator;
++ },
++ const Config extends StaticConfig = StaticConfig,
++ >(config?: Config): TypedNavigator {
++ return createNavigatorFactory(MyNavigator)(config);
++ }
+```
-TODO
+See [Custom navigators](custom-navigators.md) for usage.
-### Drawer Navigator no longer supports Reanimated 1
+#### Packages now use ESM and package exports
-TODO
+All the packages in React Navigation now use ESM exports. While it shouldn't affect most users, there are some changes to be aware of:
+
+- If you are importing internal files from the packages, they might now be restricted by your bundler and it won't be possible to import them directly. You should use the public API instead.
+- If you're patching the packages using `patch-package`, `yarn patch` etc., you'll need to patch the built files under `lib/` folders instead of the source files under `src/` as the source files are no longer exported.
+- If you're using TypeScript with the `module` or `moduleResolution` option, it maybe necessary to set `moduleResolution` to `bundler` to match [Metro's resolution behavior](https://reactnative.dev/blog/2023/06/21/package-exports-support#enabling-package-exports-beta).
+- If you're using Webpack for bundling code using React Navigation, it maybe necessary to set [`resolve.fullySpecified`](https://webpack.js.org/configuration/module/#resolvefullyspecified) to `false` for bundling to work.
## New features
-### Navigators now support a static configuration API
+### Static configuration API
+
+React Navigation 5 introduced a dynamic API to support more flexible use cases. With React Navigation 7, we are re-introducing a static configuration API:
+
+```js
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+const MyStack = createNativeStackNavigator({
+ screens: {
+ Home: {
+ screen: HomeScreen,
+ options: {
+ title: 'My App',
+ },
+ },
+ Details: {
+ screen: DetailsScreen,
+ linking: 'details/:id',
+ },
+ },
+});
+```
+
+The static configuration API provides the following benefits:
+
+- **Simpler type-checking with TypeScript**: It's not necessary to specify screens and their params separately. See [Type checking with TypeScript](typescript.md?config=static) for more details.
+- **Easier deep linking setup**: Paths can be generated automatically. Linking configuration can be defined next to the screen for explicit configuration. See [Configuring links](configuring-links.md?config=static) for more details.
+
+It's also possible to mix the static and dynamic configuration APIs. For example, you can use the static configuration API for the top-level navigators and the dynamic configuration API for the nested navigators where you need more flexibility.
+
+:::note
+
+The static configuration API doesn't replace the dynamic configuration API. Both APIs are equally supported and you can choose the one that fits your use case better.
+
+:::
+
+You can see examples for both the static and dynamic configuration APIs in the documentation by selecting the appropriate tab in the examples.
+
+Go to ["Hello React Navigation"](hello-react-navigation.md?config=static) to start writing some code with the static API.
+
+### Improved TypeScript support
+
+Previously, the `navigation` object received in `options` and `listeners` callbacks were typed as `any` and required manual type annotation. Now, the `navigation` object has a more accurate type based on the navigator it's used in, and the type annotation is no longer required.
+
+We also export a new `XOptionsArgs` (where `X` is the navigator name, e.g. `StackOptionsArgs`, `BottomTabOptionsArgs` etc.) type which can be used to type the arguments of the `options` callback. This can be useful if you want to define the options callback separately.
+
+```ts
+const options = ({
+ route,
+}: StackOptionsArgs) => {
+ return {
+ title: route.params.title,
+ };
+};
+```
+
+### Improved RTL support
+
+Previously, various UI elements used the `I18nManager` API to determine the writing direction. However, this API doesn't work well on the Web as the writing direction can be different for a specific subtree and hence can't be determined globally.
+
+The `NavigationContainer` now accepts a `direction` prop to specify the direction of the layout instead of relying on the `I18nManager` API. It also exposes this value via `useLocale` hook for use in your own components.
+
+See the [navigation container docs](navigation-container.md#direction) for usage.
+
+### The `options` callback gets `theme`
+
+The `options` callback now receives the `theme` object to allow customizing the UI elements specified in the options:
+
+```jsx
+ ({
+ headerRight: () => (
+ {}}
+ color={theme.colors.primary}
+ />
+ ),
+ })}
+/>
+```
+
+See [Screen options](screen-options.md) for usage.
+
+### Top-level `path` in linking config
+
+The linking configuration now supports a top-level `path` configuration to define the base path for all the screens in the navigator:
+
+```js
+const linking = {
+ prefixes: ['https://mysite.com'],
+ config: {
+ // highlight-next-line
+ path: 'app',
+ screens: {
+ Home: 'home',
+ Details: 'details/:id',
+ },
+ },
+};
+```
+
+This can be useful if your app lives under a subpath on the web. For example, if your app lives under `https://mysite.com/app`, you can define the `path` as `app` and the `Details` screen will be accessible at `https://mysite.com/app/details/42`.
+
+See [Configuring links](configuring-links.md#apps-under-subpaths) for usage.
+
+### Improved Web integration
+
+More built-in UI elements that trigger navigation now render `a` tags on the Web for better accessibility and SEO. This includes:
+
+- Back button in the header
+- The tab buttons in material top tab navigator
+
+UI elements such as the bottom tab bar and drawer items already rendered `a` tags on the Web.
+
+### New `usePreventRemove` hook
+
+Previously, the only way to prevent a screen from being removed from the stack was to use the `beforeRemove` event. This didn't work well with the Native Stack Navigator.
+
+The new `usePreventRemove` hook is an alternative to `beforeRemove` that works with the Native Stack Navigator.
+
+See [`usePreventRemove`](use-prevent-remove.md) for usage.
+
+### New `layout` props
+
+#### For navigators
-TODO
+Navigators now support a `layout` prop. It can be useful for augmenting the navigators with additional UI with a wrapper. The difference from adding a regular wrapper is that the code in `layout` callback has access to the navigator's state, options etc.:
-### Support a top-level `path` configuration in linking config
+```jsx
+ (
+
+
+ {children}
+
+ )}
+ // highlight-end
+>
+ {/* ... */}
+
+```
-TODO
+See [Navigator layout](navigator.md#layout) for usage.
+
+#### For screens and groups
+
+The `layout` prop makes it easier to provide things such as a global error boundary and suspense fallback for a group of screens without having to manually add HOCs for every screen separately.
+
+It can be used for a single screen with [`layout`](screen.md#layout):
+
+```jsx
+ (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ )}
+ // highlight-end
+/>
+```
-### Support custom `layout` prop for Navigators
+Or with a [group](group.md#screen-layout) or [navigator](navigator.md#screen-layout) with `screenLayout`:
+
+```jsx
+ (
+
+
+ Loading…
+
+ }
+ >
+ {children}
+
+
+ )}
+>
+ // highlight-end
+ {/* screens */}
+
+```
-TODO
+### Preloading screens
-### Add experimental API for handling deep link after authentication
+All built-in navigators now support preloading screens prior to navigating to them. This can be useful to improve the perceived performance of the app by preloading the screens that the user is likely to navigate to next. Preloading a screen will render it off-screen and execute its side-effects such as data fetching.
+
+To preload a screen, you can use the `preload` method on the navigation object:
+
+```js
+navigation.preload('Details', { id: 42 });
+```
-TODO
+See [`preload`](navigation-object.md#preload) for usage.
+
+### Improvements to navigators
+
+#### Bottom Tab Navigator can now show tabs on the side and top
+
+The `@react-navigation/bottom-tabs` package now supports showing tabs on the side. This will make it easier to build responsive UIs for where you want to show tabs on the bottom on smaller screens and switch to a sidebar on larger screens.
+
+Similarly, showing tabs on the top is also supported which can be useful for Android TV or Apple TV apps.
+
+You can use the `tabBarPosition` option to customize the position of the tabs:
+
+```jsx
+
+ {/* ... */}
+
+```
-### Add a `Button` component to Elements
+See [Bottom Tab Navigator options](bottom-tab-navigator.md#tabbarposition) for usage.
-TODO
+#### Bottom Tab Navigator now supports animations
-### Add `useAnimatedHeaderHeight` hook to Native Stack Navigator
+The `@react-navigation/bottom-tabs` package now supports animations. This was one of the most requested features on our Canny board: [TabNavigator Custom Transition](https://react-navigation.canny.io/feature-requests/p/tabnavigator-custom-transition).
-TODO
+You can use the `animation` option to customize the animations for the tab transitions:
+
+```jsx
+
+ {/* ... */}
+
+```
+
+See [Bottom Tab Navigator animation](bottom-tab-navigator.md#animations) for usage.
+
+#### Stack Navigator now supports an `animation` option
+
+The `@react-navigation/stack` package now supports an `animation` option to customize the animations for the screen transitions:
+
+```jsx
+
+ {/* ... */}
+
+```
+
+The `animation` option is an alternative to the `TransitionPresets` API, and is intended to make migrating between JS stack and native stack navigators easier.
+
+See [Stack Navigator animation](stack-navigator.md#animations) for usage.
+
+#### Native Stack Navigator now exports a `useAnimatedHeaderHeight` hook
+
+The `@react-navigation/native-stack` package now exports a `useAnimatedHeaderHeight` hook. It can be used to animate content based on the header height changes - such as when the large title shrinks to a small title on iOS:
+
+```jsx
+const headerHeight = useAnimatedHeaderHeight();
+
+return (
+
+ {/* ... */}
+
+);
+```
-### Bottom Tab Navigator now supports animations
+#### All navigators with headers now support `headerSearchBarOptions`
-TODO
+The `Header` component from `@react-navigation/elements` now supports a `headerSearchBarOptions` prop. This means all navigators that use the `Header` component now support a search bar in the header as well on all platforms. Previously, this was only available in the Native Stack Navigator on iOS and Android.
+
+```js
+React.useLayoutEffect(() => {
+ navigation.setOptions({
+ headerSearchBarOptions: {
+ placeholder: 'Search',
+ onChangeText: (text) => {
+ // Do something
+ },
+ },
+ });
+}, [navigation]);
+```
+
+See [`headerSearchBarOptions`](elements.md#headersearchbaroptions) for usage.
+
+### New components in elements library
+
+The `@react-navigation/elements` package now includes new components that can be used in your app:
+
+#### `Button`
+
+The `Button` component has built-in support for navigating to screens, and renders an anchor tag on the Web when used for navigation:
+
+```jsx
+
+ View Jane's Profile
+
+```
+
+It can also be used as a regular button:
+
+```jsx
+ {
+ /* do something */
+ }}
+>
+ Do something
+
+```
+
+The button follows the [Material Design 3 guidelines](https://m3.material.io/components/buttons/overview).
+
+See [`Button`](elements.md#button) for usage.
+
+#### `HeaderButton`
+
+The `HeaderButton` component can be used to render buttons in the header with appropriate styling:
+
+```js
+headerRight: ({ tintColor }) => (
+ {
+ /* do something */
+ }}
+ >
+
+
+),
+```
+
+See [`HeaderButton`](elements.md#headerbutton) for usage.
+
+#### `Label`
+
+The `Label` component can be used to render label text, such as the label in a tab bar button:
+
+```jsx
+Home
+```
+
+See [`Label`](elements.md#label) for usage.
+
+### `react-native-drawer-layout` package
+
+The drawer implementation used in `@react-navigation/drawer` is now available as a standalone package called `react-native-drawer-layout`. This makes it easier to use the drawer implementation even if you're not using React Navigation, or if you want to use it without a navigator.
+
+You can install it with:
+
+```bash npm2yarn
+npm install react-native-drawer-layout
+```
-### Bottom Tab Navigator can now show tabs on the side
+See [`react-native-drawer-layout`](drawer-layout.md) for usage.
-TODO
+### `useLogger` devtool
-### The drawer implementation is now available in `react-native-drawer-layout` as a standalone package
+The `@react-navigation/devtools` package now exports a `useLogger` hook. It can be used to log navigation actions to the console:
-TODO
+See [`useLogger`](devtools.md#uselogger) for usage.
diff --git a/versioned_docs/version-7.x/use-focus-effect.md b/versioned_docs/version-7.x/use-focus-effect.md
index e7494fa394b..4355798290b 100755
--- a/versioned_docs/version-7.x/use-focus-effect.md
+++ b/versioned_docs/version-7.x/use-focus-effect.md
@@ -4,30 +4,105 @@ title: useFocusEffect
sidebar_label: useFocusEffect
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
Sometimes we want to run side-effects when a screen is focused. A side effect may involve things like adding an event listener, fetching data, updating document title, etc. While this can be achieved using `focus` and `blur` events, it's not very ergonomic.
To make this easier, the library exports a `useFocusEffect` hook:
-
+
+
-```js
+```js name="useFocusEffect hook" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+// codeblock-focus-start
import { useFocusEffect } from '@react-navigation/native';
-function Profile({ userId }) {
- const [user, setUser] = React.useState(null);
-
+function ProfileScreen() {
useFocusEffect(
React.useCallback(() => {
- const unsubscribe = API.subscribe(userId, user => setUser(user));
+ // Do something when the screen is focused
+ return () => {
+ // Do something when the screen is unfocused
+ // Useful for cleanup functions
+ };
+ }, [])
+ );
- return () => unsubscribe();
- }, [userId])
+ return ;
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="useFocusEffect hook" snack
+import * as React from 'react';
+import { View } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+// codeblock-focus-start
+import { useFocusEffect } from '@react-navigation/native';
+
+function ProfileScreen() {
+ useFocusEffect(
+ React.useCallback(() => {
+ // Do something when the screen is focused
+ return () => {
+ // Do something when the screen is unfocused
+ // Useful for cleanup functions
+ };
+ }, [])
);
- return ;
+ return ;
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
:::warning
To avoid the running the effect too often, it's important to wrap the callback in `useCallback` before passing it to `useFocusEffect` as shown in the example.
@@ -107,7 +182,7 @@ useFocusEffect(
React.useCallback(() => {
return () => {
// Do something that should run on blur
- }
+ };
}, [])
);
```
@@ -116,7 +191,7 @@ The cleanup function runs whenever the effect needs to cleanup, i.e. on `blur`,
```js
React.useEffect(() => {
- const unsubscribe = navigation.addListener('blur', () => {
+ const unsubscribe = navigation.addListener('blur', () => {
// Do something when the screen blurs
});
@@ -146,7 +221,7 @@ function FetchUserData({ userId, onUpdate }) {
// ...
class Profile extends React.Component {
- _handleUpdate = user => {
+ _handleUpdate = (user) => {
// Do something with user object
};
diff --git a/versioned_docs/version-7.x/use-is-focused.md b/versioned_docs/version-7.x/use-is-focused.md
index 69ab01fdc82..b0bad164bac 100755
--- a/versioned_docs/version-7.x/use-is-focused.md
+++ b/versioned_docs/version-7.x/use-is-focused.md
@@ -4,23 +4,99 @@ title: useIsFocused
sidebar_label: useIsFocused
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
We might want to render different content based on the current focus state of the screen. The library exports a `useIsFocused` hook to make this easier:
-
+
+
-```js
+```js name="useIsFocused hook" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+// codeblock-focus-start
import { useIsFocused } from '@react-navigation/native';
-// ...
+function ProfileScreen() {
+ // This hook returns `true` if the screen is focused, `false` otherwise
+ // highlight-next-line
+ const isFocused = useIsFocused();
+
+ return (
+
+ {isFocused ? 'focused' : 'unfocused'}
+
+ );
+}
+// codeblock-focus-end
-function Profile() {
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createMaterialTopTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="useIsFocused hook" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
+// codeblock-focus-start
+import { useIsFocused } from '@react-navigation/native';
+
+function ProfileScreen() {
+ // This hook returns `true` if the screen is focused, `false` otherwise
+ // highlight-next-line
const isFocused = useIsFocused();
- return {isFocused ? 'focused' : 'unfocused'} ;
+ return (
+
+ {isFocused ? 'focused' : 'unfocused'}
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createMaterialTopTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
-Note that using this hook triggers a re-render for the component when the screen it's in changes focus. This might cause lags during the animation if your component is heavy. You might want to extract the expensive parts to separate components and use [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) or [`React.PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) to minimize re-renders for them.
+
+
+
+Note that using this hook triggers a re-render for the component when the screen it's in changes focus. This might cause lags during the animation if your component is heavy. You might want to extract the expensive parts to separate components and use [`React.memo`](https://react.dev/reference/react/memo) or [`React.PureComponent`](https://react.dev/reference/react/PureComponent) to minimize re-renders for them.
## Using with class component
@@ -35,7 +111,7 @@ class Profile extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const isFocused = useIsFocused();
return ;
diff --git a/versioned_docs/version-7.x/use-link-builder.md b/versioned_docs/version-7.x/use-link-builder.md
index aab2334701a..dcb3da963f7 100644
--- a/versioned_docs/version-7.x/use-link-builder.md
+++ b/versioned_docs/version-7.x/use-link-builder.md
@@ -4,14 +4,14 @@ title: useLinkBuilder
sidebar_label: useLinkBuilder
---
-The `useLinkBuilder` hook returns helpers to build `href` or action based on the linking options. It returns an object with the following properties:
+The `useLinkBuilder` hook returns helpers to build `href` or action based on the [`linking` configuration](configuring-links.md). It returns an object with the following properties:
- [`buildHref`](#buildhref)
- [`buildAction`](#buildaction)
## `buildHref`
-The `buildHref` method lets us build a path to use for links for a screen in the current navigator's state. It returns a function that takes `name` and `params` for the screen to focus and returns path based on the [`linking` options](navigation-container.md#linking).
+The `buildHref` method lets us build a path to use for links for a screen in the current navigator's state. It returns a function that takes `name` and `params` for the screen to focus and returns path based on the [`linking` configuration](configuring-links.md).
```js
import { useLinkBuilder } from '@react-navigation/native';
diff --git a/versioned_docs/version-7.x/use-navigation-state.md b/versioned_docs/version-7.x/use-navigation-state.md
index 59bdc9b67f3..909445d16b4 100755
--- a/versioned_docs/version-7.x/use-navigation-state.md
+++ b/versioned_docs/version-7.x/use-navigation-state.md
@@ -4,6 +4,9 @@ title: useNavigationState
sidebar_label: useNavigationState
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`useNavigationState` is a hook which gives access to the [navigation state](navigation-state.md) of the navigator which contains the screen. It's useful in rare cases where you want to render something based on the navigation state.
:::warning
@@ -15,13 +18,13 @@ Consider the navigator's state object to be internal and subject to change in a
It takes a selector function as an argument. The selector will receive the full [navigation state](navigation-state.md) and can return a specific value from the state:
```js
-const index = useNavigationState(state => state.index);
+const index = useNavigationState((state) => state.index);
```
The selector function helps to reduce unnecessary re-renders, so your screen will re-render only when that's something you care about. If you actually need the whole state object, you can do this explicitly:
```js
-const state = useNavigationState(state => state);
+const state = useNavigationState((state) => state);
```
:::warning
@@ -44,16 +47,201 @@ function Profile() {
In this example, even if you push a new screen, this text won't update. If you use the hook, it'll work as expected:
-
+
+
-```js
-function Profile() {
- const routesLength = useNavigationState(state => state.routes.length);
+```js name="useNavigation hook" snack
+import * as React from 'react';
+import Button from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ createStaticNavigation,
+ useNavigation,
+ useRoute,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
+import { useNavigationState } from '@react-navigation/native';
- return Number of routes: {routesLength} ;
+function useIsFirstRouteInParent() {
+ const route = useRoute();
+ const isFirstRouteInParent = useNavigationState(
+ (state) => state.routes[0].key === route.key
+ );
+
+ return isFirstRouteInParent;
+}
+
+function usePreviousRouteName() {
+ return useNavigationState((state) =>
+ state.routes[state.index - 1]?.name
+ ? state.routes[state.index - 1].name
+ : 'None'
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const isFirstRoute = useIsFirstRouteInParent();
+ const previousRouteName = usePreviousRouteName();
+ return (
+
+ It is {isFirstRoute ? '' : 'not '}first route in navigator
+ Previous route name: {previousRouteName}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const navigation = useNavigation();
+ const isFirstRoute = useIsFirstRouteInParent();
+ const previousRouteName = usePreviousRouteName();
+ return (
+
+ It is {isFirstRoute ? '' : 'not '}first route in navigator
+ Previous route name: {previousRouteName}
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+ navigation.goBack()}>Go back
+
+ );
+}
+
+function SettingsScreen() {
+ const navigation = useNavigation();
+ const isFirstRoute = useIsFirstRouteInParent();
+ const previousRouteName = usePreviousRouteName();
+ return (
+
+ It is {isFirstRoute ? '' : 'not '}first route in navigator
+ Previous route name: {previousRouteName}
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createNativeStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="useNavigationState hook" snack
+import * as React from 'react';
+import Button from '@react-navigation/elements';
+import { View, Text } from 'react-native';
+import {
+ NavigationContainer,
+ useRoute,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+
+// codeblock-focus-start
+import { useNavigationState } from '@react-navigation/native';
+
+function useIsFirstRouteInParent() {
+ const route = useRoute();
+ const isFirstRouteInParent = useNavigationState(
+ (state) => state.routes[0].key === route.key
+ );
+
+ return isFirstRouteInParent;
+}
+
+function usePreviousRouteName() {
+ return useNavigationState((state) =>
+ state.routes[state.index - 1]?.name
+ ? state.routes[state.index - 1].name
+ : 'None'
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen({ navigation }) {
+ const isFirstRoute = useIsFirstRouteInParent();
+ const previousRouteName = usePreviousRouteName();
+ return (
+
+ It is {isFirstRoute ? '' : 'not '}first route in navigator
+ Previous route name: {previousRouteName}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen({ navigation }) {
+ const isFirstRoute = useIsFirstRouteInParent();
+ const previousRouteName = usePreviousRouteName();
+ return (
+
+ It is {isFirstRoute ? '' : 'not '}first route in navigator
+ Previous route name: {previousRouteName}
+ navigation.navigate('Settings')}>
+ Go to Settings
+
+ navigation.goBack()}>Go back
+
+ );
+}
+
+function SettingsScreen({ navigation }) {
+ const isFirstRoute = useIsFirstRouteInParent();
+ const previousRouteName = usePreviousRouteName();
+ return (
+
+ It is {isFirstRoute ? '' : 'not '}first route in navigator
+ Previous route name: {previousRouteName}
+ navigation.goBack()}>Go back
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+function MyStack() {
+ return (
+
+
+
+
+
+ );
+}
+
+export default function App() {
+ return (
+
+
+
+ );
}
```
+
+
+
So when do you use `navigation.getState()`? It's mostly useful within event listeners where you don't care about what's rendered. In most cases, using the hook should be preferred.
## Using with class component
@@ -69,8 +257,8 @@ class Profile extends React.Component {
}
// Wrap and export
-export default function(props) {
- const routesLength = useNavigationState(state => state.routes.length);
+export default function (props) {
+ const routesLength = useNavigationState((state) => state.routes.length);
return ;
}
diff --git a/versioned_docs/version-7.x/use-navigation.md b/versioned_docs/version-7.x/use-navigation.md
index 07d0cfff595..b0a6e35396e 100755
--- a/versioned_docs/version-7.x/use-navigation.md
+++ b/versioned_docs/version-7.x/use-navigation.md
@@ -4,31 +4,147 @@ title: useNavigation
sidebar_label: useNavigation
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`useNavigation` is a hook that gives access to `navigation` object. It's useful when you cannot pass the `navigation` object as a prop to the component directly, or don't want to pass it in case of a deeply nested child.
The `useNavigation` hook returns the `navigation` object of the screen where it's used:
-
+
+
-```js
+```js name="useNavigation hook" snack
import * as React from 'react';
-import { Button } from 'react-native';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { createStaticNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
import { useNavigation } from '@react-navigation/native';
function MyBackButton() {
+ // highlight-next-line
const navigation = useNavigation();
return (
{
navigation.goBack();
}}
- />
+ >
+ Back
+
);
}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile Screen
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
```
+
+
+
+```js name="useNavigation hook" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
+import { useNavigation } from '@react-navigation/native';
+
+function MyBackButton() {
+ // highlight-next-line
+ const navigation = useNavigation();
+
+ return (
+ {
+ navigation.goBack();
+ }}
+ >
+ Back
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen({ navigation: { navigate } }) {
+ return (
+
+ This is the home screen of the app
+ navigate('Profile')}>Go to Profile
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile Screen
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default App;
+```
+
+
+
+
+Check how to setup `useNavigation` with TypeScript [here](typescript.md#annotating-usenavigation).
+
See the documentation for the [`navigation` object](navigation-object.md) for more info.
## Using with class component
@@ -44,7 +160,7 @@ class MyBackButton extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const navigation = useNavigation();
return ;
diff --git a/versioned_docs/version-7.x/use-prevent-remove.md b/versioned_docs/version-7.x/use-prevent-remove.md
new file mode 100644
index 00000000000..d13b5af31f3
--- /dev/null
+++ b/versioned_docs/version-7.x/use-prevent-remove.md
@@ -0,0 +1,281 @@
+---
+id: use-prevent-remove
+title: usePreventRemove
+sidebar_label: usePreventRemove
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+The `usePreventRemove` hook allows you to prevent the user from leaving a screen. For example, if there are unsaved changes, you might want to show a confirmation dialog before the user can navigate away.
+
+The hook takes 2 parameters:
+
+- `preventRemove`: A boolean value indicating whether to prevent the screen from being removed.
+- `callback`: A function that will be called when the removal is prevented. This can be used to show a confirmation dialog.
+
+The callback receives a `data` object with the `action` that triggered the removal of the screen. You can dispatch this action again after confirmation, or check the action object to determine what to do.
+
+Example:
+
+
+
+
+```js name="usePreventRemove hook" snack
+import * as React from 'react';
+import { Alert, View, TextInput, Platform, StyleSheet } from 'react-native';
+import {
+ useNavigation,
+ usePreventRemove,
+ createStaticNavigation,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+const EditTextScreen = () => {
+ const [text, setText] = React.useState('');
+ const navigation = useNavigation();
+
+ const hasUnsavedChanges = Boolean(text);
+
+ usePreventRemove(hasUnsavedChanges, ({ data }) => {
+ if (Platform.OS === 'web') {
+ const discard = confirm(
+ 'You have unsaved changes. Discard them and leave the screen?'
+ );
+
+ if (discard) {
+ navigation.dispatch(data.action);
+ }
+ } else {
+ Alert.alert(
+ 'Discard changes?',
+ 'You have unsaved changes. Discard them and leave the screen?',
+ [
+ { text: "Don't leave", style: 'cancel', onPress: () => {} },
+ {
+ text: 'Discard',
+ style: 'destructive',
+ onPress: () => navigation.dispatch(data.action),
+ },
+ ]
+ );
+ }
+ });
+
+ return (
+
+
+
+ );
+};
+// codeblock-focus-end
+
+const HomeScreen = () => {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.push('EditText')} style={styles.button}>
+ Push EditText
+
+
+ );
+};
+
+const RootStack = createStackNavigator({
+ screens: {
+ Home: HomeScreen,
+ EditText: EditTextScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(RootStack);
+
+export default function App() {
+ return ;
+}
+
+const styles = StyleSheet.create({
+ content: {
+ flex: 1,
+ padding: 16,
+ },
+ input: {
+ margin: 8,
+ padding: 10,
+ borderRadius: 3,
+ borderWidth: StyleSheet.hairlineWidth,
+ borderColor: 'rgba(0, 0, 0, 0.08)',
+ backgroundColor: 'white',
+ },
+ buttons: {
+ flex: 1,
+ justifyContent: 'center',
+ padding: 8,
+ },
+ button: {
+ margin: 8,
+ },
+});
+```
+
+
+
+
+```js name="usePreventRemove hook" snack
+import * as React from 'react';
+import { Alert, View, TextInput, Platform, StyleSheet } from 'react-native';
+import {
+ NavigationContainer,
+ useNavigation,
+ usePreventRemove,
+} from '@react-navigation/native';
+import { createStackNavigator } from '@react-navigation/stack';
+import { Button } from '@react-navigation/elements';
+
+// codeblock-focus-start
+const EditTextScreen = () => {
+ const navigation = useNavigation();
+ const [text, setText] = React.useState('');
+
+ const hasUnsavedChanges = Boolean(text);
+
+ usePreventRemove(hasUnsavedChanges, ({ data }) => {
+ if (Platform.OS === 'web') {
+ // Alert is not supported on web, so we can use confirm
+ const discard = confirm(
+ 'You have unsaved changes. Discard them and leave the screen?'
+ );
+
+ if (discard) {
+ navigation.dispatch(data.action);
+ }
+ } else {
+ // Prompt the user before leaving the screen
+ Alert.alert(
+ 'Discard changes?',
+ 'You have unsaved changes. Discard them and leave the screen?',
+ [
+ {
+ text: "Don't leave",
+ style: 'cancel',
+ onPress: () => {
+ // Do nothingP
+ },
+ },
+ {
+ text: 'Discard',
+ style: 'destructive',
+ onPress: () => navigation.dispatch(data.action),
+ },
+ ]
+ );
+ }
+ });
+
+ return (
+
+
+
+ );
+};
+// codeblock-focus-end
+
+const HomeScreen = () => {
+ const navigation = useNavigation();
+
+ return (
+
+ navigation.push('EditText')} style={styles.button}>
+ Push EditText
+
+
+ );
+};
+
+const Stack = createStackNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ content: {
+ flex: 1,
+ padding: 16,
+ },
+ input: {
+ margin: 8,
+ padding: 10,
+ borderRadius: 3,
+ borderWidth: StyleSheet.hairlineWidth,
+ borderColor: 'rgba(0, 0, 0, 0.08)',
+ backgroundColor: 'white',
+ },
+ buttons: {
+ flex: 1,
+ justifyContent: 'center',
+ padding: 8,
+ },
+ button: {
+ margin: 8,
+ },
+});
+```
+
+
+
+
+
+
+
+
+Internally, the hook uses the [`beforeRemove`](navigation-events.md#beforeremove) event to prevent the screen from being removed. This event is triggered whenever a screen is being removed due to a navigation action.
+
+## Limitations
+
+There are a couple of limitations to be aware of when using the `usePreventRemove` hook. It is **only** triggered whenever a screen is being removed due to a navigation state change. For example:
+
+- The user pressed the back button on a screen in a stack.
+- The user performed a swipe-back gesture.
+- Some action such as `pop` or `reset` was dispatched which removes the screen from the state.
+
+It **does not prevent** a screen from being unfocused if it's not being removed. For example:
+
+- The user pushed a new screen on top of the screen with the listener in a stack.
+- The user navigated from one tab/drawer screen to another tab/drawer screen.
+
+It also **does not prevent** a screen from being removed when the user is exiting the screen due to actions not controlled by the navigation state:
+
+- The user closes the app (e.g. by pressing the back button on the home screen, closing the tab in the browser, closing it from the app switcher etc.). You can additionally use [`hardwareBackPress`](https://reactnative.dev/docs/backhandler) event on Android, [`beforeunload`](https://developer.mozilla.org/en-US/docs/web/api/window/beforeunload_event) event on the Web etc. to handle some of these cases. See [Prevent the user from leaving the app](preventing-going-back.md#prevent-the-user-from-leaving-the-app) for more details.
+- A screen gets unmounted due to conditional rendering, or due to a parent component being unmounted.
+
+## UX considerations
+
+Generally, we recommend using this hook sparingly. A better approach is to persist the unsaved data into [`AsyncStorage`](https://github.com/react-native-async-storage/async-storage) or similar persistent storage and prompt to restore it when the user returns to the screen.
+
+Doing so has several benefits:
+
+- This approach still works if the app is closed or crashes unexpectedly.
+- It's less intrusive to the user as they can still navigate away from the screen to check something and return without losing the data.
diff --git a/versioned_docs/version-7.x/use-route-path.md b/versioned_docs/version-7.x/use-route-path.md
new file mode 100644
index 00000000000..530bc324cb7
--- /dev/null
+++ b/versioned_docs/version-7.x/use-route-path.md
@@ -0,0 +1,25 @@
+---
+id: use-route-path
+title: useRoutePath
+sidebar_label: useRoutePath
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+The `useRoutePath` hook can be used to get the path of a route based on the [`linking` configuration](configuring-links.md). This can be useful if you need to generate a URL for a specific route in your app to share as a deep link.
+
+## Example
+
+```js
+import { useRoutePath } from '@react-navigation/native';
+
+function MyComponent() {
+ const path = useRoutePath();
+
+ // Construct a URL using the path and app's base URL
+ const url = new URL(path, 'https://example.com');
+
+ return Shareable URL: {url.href} ;
+}
+```
diff --git a/versioned_docs/version-7.x/use-route.md b/versioned_docs/version-7.x/use-route.md
index 0b5d74891af..05cba0813e8 100755
--- a/versioned_docs/version-7.x/use-route.md
+++ b/versioned_docs/version-7.x/use-route.md
@@ -4,26 +4,146 @@ title: useRoute
sidebar_label: useRoute
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
`useRoute` is a hook which gives access to `route` object. It's useful when you cannot pass down the `route` object from props to the component, or don't want to pass it in case of a deeply nested child.
`useRoute()` returns the `route` object of the screen it's inside.
## Example
-
+
+
-```js
+```js name="useRoute hook" snack
import * as React from 'react';
-import { Text } from 'react-native';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import {
+ createStaticNavigation,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
import { useRoute } from '@react-navigation/native';
function MyText() {
+ // highlight-next-line
const route = useRoute();
return {route.params.caption} ;
}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', { caption: 'Some caption' });
+ }}
+ >
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile Screen
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator({
+ initialRouteName: 'Home',
+ screens: {
+ Home: HomeScreen,
+ Profile: ProfileScreen,
+ },
+});
+
+const Navigation = createStaticNavigation(Stack);
+
+function App() {
+ return ;
+}
+
+export default App;
```
+
+
+
+```js name="useRoute hook" snack
+import * as React from 'react';
+import { View, Text } from 'react-native';
+import { Button } from '@react-navigation/elements';
+import { NavigationContainer, useNavigation } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+// codeblock-focus-start
+import { useRoute } from '@react-navigation/native';
+
+function MyText() {
+ // highlight-next-line
+ const route = useRoute();
+
+ return {route.params.caption} ;
+}
+// codeblock-focus-end
+
+function HomeScreen({ navigation }) {
+ return (
+
+ This is the home screen of the app
+ {
+ navigation.navigate('Profile', { caption: 'Some caption' });
+ }}
+ >
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ return (
+
+ Profile Screen
+
+
+ );
+}
+
+const Stack = createNativeStackNavigator();
+
+function App() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default App;
+```
+
+
+
+
+Check how to setup `useRoute` with TypeScript [here](typescript.md#annotating-useroute).
+
See the documentation for the [`route` object](route-object.md) for more info.
## Using with class component
@@ -39,7 +159,7 @@ class MyText extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const route = useRoute();
return ;
diff --git a/versioned_docs/version-7.x/use-scroll-to-top.md b/versioned_docs/version-7.x/use-scroll-to-top.md
index a4153d0dda1..02e89c808bf 100755
--- a/versioned_docs/version-7.x/use-scroll-to-top.md
+++ b/versioned_docs/version-7.x/use-scroll-to-top.md
@@ -4,28 +4,148 @@ title: useScrollToTop
sidebar_label: useScrollToTop
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
The expected native behavior of scrollable components is to respond to events from navigation that will scroll to top when tapping on the active tab as you would expect from native tab bars.
In order to achieve it we export `useScrollToTop` which accept ref to scrollable component (e,g. `ScrollView` or `FlatList`).
Example:
-
+
+
-```js
+```js name="useScrollToTop hook" snack
+import * as React from 'react';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { createStaticNavigation } from '@react-navigation/native';
+import { View, Image } from 'react-native';
+// codeblock-focus-start
+import { ScrollView } from 'react-native';
+import { useScrollToTop } from '@react-navigation/native';
+
+function Albums() {
+ const ref = React.useRef(null);
+
+ // highlight-next-line
+ useScrollToTop(ref);
+
+ return (
+
+ {/* content */}
+ // codeblock-focus-end
+
+
+
+
+ // codeblock-focus-start
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator({
+ Home: HomeScreen,
+ Albums: Albums,
+});
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="useScrollToTop hook" snack
import * as React from 'react';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { View, Image } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+// codeblock-focus-start
import { ScrollView } from 'react-native';
import { useScrollToTop } from '@react-navigation/native';
function Albums() {
const ref = React.useRef(null);
+ // highlight-next-line
useScrollToTop(ref);
- return {/* content */} ;
+ return (
+
+ {/* content */}
+ // codeblock-focus-end
+
+
+
+
+ // codeblock-focus-start
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
## Using with class component
You can wrap your class component in a function component to use the hook:
@@ -51,10 +171,85 @@ export default function (props) {
If you require offset to scroll position you can wrap and decorate passed reference:
-
+
+
-```js
+```js name="useScrollToTop hook - providing scroll offset" snack
+import * as React from 'react';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { View, Image } from 'react-native';
+import { createStaticNavigation } from '@react-navigation/native';
+
+// codeblock-focus-start
+import { ScrollView } from 'react-native';
+import { useScrollToTop } from '@react-navigation/native';
+
+function Albums() {
+ const ref = React.useRef(null);
+
+ useScrollToTop(
+ React.useRef({
+ scrollToTop: () => ref.current?.scrollTo({ y: 100 }),
+ })
+ );
+
+ return (
+
+ {/* content */}
+ // codeblock-focus-end
+
+
+
+
+ // codeblock-focus-start
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator({
+ screens: {
+ Home: HomeScreen,
+ Albums: Albums,
+ },
+});
+
+const Navigation = createStaticNavigation(Tab);
+
+export default function App() {
+ return ;
+}
+```
+
+
+
+
+```js name="useScrollToTop hook - providing scroll offset" snack
import * as React from 'react';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { View, Image } from 'react-native';
+import { NavigationContainer } from '@react-navigation/native';
+// codeblock-focus-start
import { ScrollView } from 'react-native';
import { useScrollToTop } from '@react-navigation/native';
@@ -67,6 +262,53 @@ function Albums() {
})
);
- return {/* content */} ;
+ return (
+
+ {/* content */}
+ // codeblock-focus-end
+
+
+
+
+ // codeblock-focus-start
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ return ;
+}
+
+const Tab = createBottomTabNavigator();
+
+export default function App() {
+ return (
+
+
+
+
+
+
+ );
}
```
+
+
+
diff --git a/versioned_docs/version-7.x/use-theme.md b/versioned_docs/version-7.x/use-theme.md
index 7807e031e70..13df9b4640f 100644
--- a/versioned_docs/version-7.x/use-theme.md
+++ b/versioned_docs/version-7.x/use-theme.md
@@ -4,17 +4,62 @@ title: useTheme
sidebar_label: useTheme
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
The `useTheme` hook lets us access the currently active theme. You can use it in your own components to have them respond to changes in the theme.
-
+
+
-```js
+```js name="useTheme hook" snack
import * as React from 'react';
-import { TouchableOpacity, Text } from 'react-native';
+import {
+ useNavigation,
+ createStaticNavigation,
+ DefaultTheme,
+ DarkTheme,
+} from '@react-navigation/native';
+import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
import { useTheme } from '@react-navigation/native';
-// Black background and white text in light theme, inverted on dark theme
+// codeblock-focus-end
+
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+ const { user } = route.params;
+ const { colors } = useTheme();
+
+ return (
+
+ Settings Screen
+
+ userParam: {JSON.stringify(user)}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+
+function ProfileScreen() {
+ const { colors } = useTheme();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+// codeblock-focus-start
function MyButton() {
+ // highlight-next-line
const { colors } = useTheme();
return (
@@ -23,8 +68,172 @@ function MyButton() {
);
}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const { colors } = useTheme();
+
+ return (
+
+ Home Screen
+
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const PanelStack = createNativeStackNavigator({
+ screens: {
+ Profile: ProfileScreen,
+ Settings: SettingsScreen,
+ },
+});
+
+const Drawer = createDrawerNavigator({
+ initialRouteName: 'Panel',
+ screens: {
+ Home: HomeScreen,
+ Panel: {
+ screen: PanelStack,
+ options: {
+ headerShown: false,
+ },
+ },
+ },
+});
+
+const Navigation = createStaticNavigation(Drawer);
+
+export default function App() {
+ const scheme = useColorScheme();
+ return ;
+}
```
+
+
+
+```js name="useTheme hook" snack
+import * as React from 'react';
+import { View, Text, TouchableOpacity, useColorScheme } from 'react-native';
+import {
+ NavigationContainer,
+ DefaultTheme,
+ DarkTheme,
+ useNavigation,
+} from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Button } from '@react-navigation/elements';
+// codeblock-focus-start
+import { useTheme } from '@react-navigation/native';
+
+// codeblock-focus-end
+function SettingsScreen({ route }) {
+ const navigation = useNavigation();
+ const { user } = route.params;
+ const { colors } = useTheme();
+
+ return (
+
+ Settings Screen
+
+ userParam: {JSON.stringify(user)}
+
+ navigation.navigate('Profile')}>
+ Go to Profile
+
+
+ );
+}
+function ProfileScreen() {
+ const { colors } = useTheme();
+
+ return (
+
+ Profile Screen
+
+ );
+}
+
+// codeblock-focus-start
+function MyButton() {
+ // highlight-next-line
+ const { colors } = useTheme();
+
+ return (
+
+ Button!
+
+ );
+}
+// codeblock-focus-end
+
+function HomeScreen() {
+ const navigation = useNavigation();
+ const { colors } = useTheme();
+
+ return (
+
+ Home Screen
+
+
+ navigation.navigate('Root', {
+ screen: 'Settings',
+ params: { user: 'jane' },
+ })
+ }
+ >
+ Go to Settings
+
+
+ );
+}
+
+const Drawer = createDrawerNavigator();
+const Stack = createNativeStackNavigator();
+
+function Root() {
+ return (
+
+
+
+
+ );
+}
+
+export default function App() {
+ const scheme = useColorScheme();
+
+ return (
+
+
+
+
+
+
+ );
+}
+```
+
+
+
+
See [theming guide](themes.md) for more details and usage guide around how to configure themes.
## Using with class component
@@ -40,7 +249,7 @@ class MyButton extends React.Component {
}
// Wrap and export
-export default function(props) {
+export default function (props) {
const theme = useTheme();
return ;
diff --git a/versioned_docs/version-7.x/web-support.md b/versioned_docs/version-7.x/web-support.md
index 5b1e47a5bdc..c3625c0282d 100755
--- a/versioned_docs/version-7.x/web-support.md
+++ b/versioned_docs/version-7.x/web-support.md
@@ -1,33 +1,160 @@
---
id: web-support
-title: React Navigation on the Web
+title: React Navigation on Web
sidebar_label: Web support
---
-:::warning
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
-Support for web is experimental and a work in progress. It has bugs, is missing many features and the API for web integration may change in minor versions. Please help us test it and open bug reports if you encounter a bug.
+React Navigation has built-in support for the Web platform. This allows you to use the same navigation logic in your React Native app as well as on the web. The navigators require using [React Native for Web](https://github.com/necolas/react-native-web) to work on the web.
-:::
+## Pre-requisites
+
+While Web support works out of the box, there are some things to configure to ensure a good experience on the web:
+
+1. [**Configure linking**](configuring-links.md)
+
+ Configuring linking allows React Navigation to integrate with the browser's URL bar. This is crucial for web apps to have proper URLs for each screen.
+
+2. [**Use Button or Link components**](link.md)
-React Navigation's web support currently requires using [React Native for Web](https://github.com/necolas/react-native-web). This approach lets us reuse the same code on both React Native and Web.
+ You may be familiar with using `navigation.navigate` to navigate between screens. But it's important to avoid using it when supporting the web. Instead, use the `Link` or [`Button`](elements.md#button) components to navigate between screens. This ensures that an anchor tag is rendered which provides the expected behavior on the web.
-Currently, the following features are available:
+3. [**Server rendering**](server-rendering.md)
-- [URL integration in browser](configuring-links.md)
-- [Accessible links](link.md)
-- [Server rendering](server-rendering.md)
+ Currently, React Navigation works best with fully client-side rendered apps. However, minimal server-side rendering support is available. So you can optionally choose to server render your app.
-It's important to use links as the primary way of navigation instead of navigation actions such as `navigation.navigate`. It'll ensure that your links are properly usable on web.
+4. **Adapt to web-specific behavior**
-Some of the navigators are also configured differently on web or provide additional web specific features:
+ Depending on your app's requirements and design, you may also want to tweak some of the navigators' behavior on the web. For example:
-1. The [drawer](drawer-navigator.md) and [bottom tab](bottom-tab-navigator.md) navigators show hyperlinks in the drawer sidebar and tab bar respectively.
-2. Swipe gestures are not available on [drawer](drawer-navigator.md) and [stack](stack-navigator.md) navigators when using on the web.
-3. By default, [stack](stack-navigator.md) navigator disables page transition animations, but it can be re-enabled by specifying `animationEnabled: true`.
+ - Change `backBehavior` to `fullHistory` for [tabs](bottom-tab-navigator.md#backbehavior) and [drawer](drawer-navigator.md#backbehavior) on the web to always push a new entry to the browser history.
+ - Use sidebars on larger screens instead of [bottom tabs](bottom-tab-navigator.md#tabbarposition) - while not specific to web, responsive design much more important on the web.
:::note
-Unlike React Navigation 4, you don't need to install a separate package to use web integration when using React Native for Web. If you have the `@react-navigation/web` package installed, please uninstall it because it cannot be used with React Navigation 6.
+In React Navigation 4, it was necessary to install a separate package called `@react-navigation/web` to use web integration. This package is no longer needed in recent versions of React Navigation. If you have it installed, make sure to uninstall it to avoid conflicts.
+
+:::
+
+## Lazy loading screens
+
+By default, screen components are bundled in the main bundle. This can lead to a large bundle size if you have many screens. It's important to keep the bundle size small on the web for faster loading times.
+
+To reduce the bundle size, you can use [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) with [`React.lazy`](https://react.dev/reference/react/lazy) to lazy load screens:
+
+
+
+
+```js name="Lazy loading screens" snack
+import { Suspense, lazy } from 'react';
+
+const MyStack = createNativeStackNavigator({
+ screenLayout: ({ children }) => (
+ }>{children}
+ ),
+ screens: {
+ Home: {
+ component: lazy(() => import('./HomeScreen')),
+ },
+ Profile: {
+ component: lazy(() => import('./ProfileScreen')),
+ },
+ },
+});
+```
+
+
+
+
+```js name="Lazy loading screens" snack
+import { Suspense, lazy } from 'react';
+
+const HomeScreen = lazy(() => import('./HomeScreen'));
+const ProfileScreen = lazy(() => import('./ProfileScreen'));
+
+function MyStack() {
+ return (
+ (
+ }>{children}
+ )}
+ >
+
+
+
+ );
+}
+```
+
+:::warning
+
+Make sure to use `React.lazy` **outside** the component containing the navigator configuration. Otherwise, it will return a new component on each render, causing the [screen to be unmounted and remounted](troubleshooting.md#screens-are-unmountingremounting-during-navigation) every time the component rerenders.
:::
+
+
+
+
+This will split the screen components into separate chunks (depending on your bundler) which are loaded on-demand when the screen is rendered. This can significantly reduce the initial bundle size.
+
+In addition, you can use the [`screenLayout`](navigator.md#screen-layout) to wrap your screens in a [``](https://react.dev/reference/react/Suspense) boundary. The suspense fallback can be used to show a loading indicator and will be shown while the screen component is being loaded.
+
+## Web-specific behavior
+
+Some of the navigators have different behavior on the web compared to native platforms:
+
+1. [**Native Stack Navigator**](stack-navigator.md)
+
+ Native Stack Navigator uses the platform's primitives to handle animations and gestures on native platforms. However, animations and gestures are not supported on the web.
+
+2. [**Stack Navigator**](stack-navigator.md)
+
+ Stack Navigator uses [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) to handle swipe gestures on native platforms. However, gestures are not supported on the web.
+
+ In addition, screen transitions are disabled by default on the web. You can enable them by setting `animationEnabled: true` in the navigator's options.
+
+3. [**Drawer Navigator**](drawer-navigator.md)
+
+ Drawer Navigator uses [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/) to handle swipe gestures and [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/) for animations on native platforms. However, gestures are not supported on the web, and animations are handled using CSS transitions.
+
+In addition, navigators render hyperlinks on the web when possible, such as in the drawer sidebar, tab bar, stack navigator's back button, etc.
+
+Since `react-native-gesture-handler` and `react-native-reanimated` are not used on the web, avoid importing them in your own code to reduce the bundle size unless you need them for your components. You can use `.native.js` or `.native.ts` extensions for code specific to native platforms.
+
+## Configuring hosting providers
+
+React Navigation is designed for Single Page Applications (SPAs). This usually means that the `index.html` file needs to be served for all routes.
+
+During development, the bundler such as Webpack or Metro automatically handles this. However, when deploying the site, you may need to configure redirects to ensure that the `index.html` file is served for all routes to avoid 404 errors.
+
+Here are instructions for some of the popular hosting providers:
+
+### Netlify
+
+To handle redirects on Netlify, add the following in the `netlify.toml` file at the root of your project:
+
+```toml
+[[redirects]]
+ from = "/*"
+ to = "/index.html"
+ status = 200
+```
+
+### Vercel
+
+To handle redirects on Vercel, add the following in the `vercel.json` file at the root of your project:
+
+```json
+{
+ "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
+}
+```
+
+### GitHub Pages
+
+GitHub Pages doesn't support such redirection configuration for SPAs. There are a couple of ways to work around this:
+
+- Rename your `index.html` to `404.html`. This will serve the `404.html` file for all routes. However, this will cause a 404 status code to be returned for all routes. So it's not ideal for SEO.
+- Write a script that copies the `index.html` file to all routes in the build output. For example, if your app has routes `/`, `/about`, and `/contact`, you can copy the `index.html` file to `about.html` and `contact.html`.
diff --git a/versioned_sidebars/version-1.x-sidebars.json b/versioned_sidebars/version-1.x-sidebars.json
index d8d5cfe5eb6..089b6bb1428 100644
--- a/versioned_sidebars/version-1.x-sidebars.json
+++ b/versioned_sidebars/version-1.x-sidebars.json
@@ -33,11 +33,7 @@
"navigation-views",
"transitioner"
],
- "Meta": [
- "pitch",
- "alternatives",
- "contributing"
- ]
+ "Meta": ["pitch", "alternatives", "contributing"]
},
"api": {
"API reference": [
diff --git a/versioned_sidebars/version-2.x-sidebars.json b/versioned_sidebars/version-2.x-sidebars.json
index 3e6341c1c39..9654b512d8a 100644
--- a/versioned_sidebars/version-2.x-sidebars.json
+++ b/versioned_sidebars/version-2.x-sidebars.json
@@ -45,11 +45,7 @@
"community-libraries-and-navigators",
"more-resources"
],
- "Meta": [
- "pitch",
- "alternatives",
- "contributing"
- ]
+ "Meta": ["pitch", "alternatives", "contributing"]
},
"version-2.x-api": {
"API reference": [
diff --git a/versioned_sidebars/version-3.x-sidebars.json b/versioned_sidebars/version-3.x-sidebars.json
index 47b15d4715d..0c2462691e4 100644
--- a/versioned_sidebars/version-3.x-sidebars.json
+++ b/versioned_sidebars/version-3.x-sidebars.json
@@ -44,6 +44,7 @@
"navigation-events",
{
"type": "category",
+ "collapsible": true,
"label": "Navigators",
"items": [
"stack-navigator",
@@ -57,6 +58,7 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Actions",
"items": [
"navigation-actions",
@@ -67,12 +69,9 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Helpers",
- "items": [
- "with-navigation",
- "with-navigation-focus",
- "scrollables"
- ]
+ "items": ["with-navigation", "with-navigation-focus", "scrollables"]
}
],
"Build your own Navigator": [
@@ -87,10 +86,6 @@
"community-libraries-and-navigators",
"more-resources"
],
- "Meta": [
- "pitch",
- "alternatives",
- "contributing"
- ]
+ "Meta": ["pitch", "alternatives", "contributing"]
}
}
diff --git a/versioned_sidebars/version-4.x-sidebars.json b/versioned_sidebars/version-4.x-sidebars.json
index 460cf239618..9fc89322ee7 100644
--- a/versioned_sidebars/version-4.x-sidebars.json
+++ b/versioned_sidebars/version-4.x-sidebars.json
@@ -46,6 +46,7 @@
"navigation-events",
{
"type": "category",
+ "collapsible": true,
"label": "Navigators",
"items": [
"stack-navigator",
@@ -60,6 +61,7 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Actions",
"items": [
"navigation-actions",
@@ -70,12 +72,9 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Helpers",
- "items": [
- "with-navigation",
- "with-navigation-focus",
- "scrollables"
- ]
+ "items": ["with-navigation", "with-navigation-focus", "scrollables"]
}
],
"Build your own Navigator": [
@@ -90,10 +89,6 @@
"community-libraries-and-navigators",
"more-resources"
],
- "Meta": [
- "pitch",
- "alternatives",
- "contributing"
- ]
+ "Meta": ["pitch", "alternatives", "contributing"]
}
}
diff --git a/versioned_sidebars/version-5.x-sidebars.json b/versioned_sidebars/version-5.x-sidebars.json
index ad9d79eb5b8..1b11455bceb 100644
--- a/versioned_sidebars/version-5.x-sidebars.json
+++ b/versioned_sidebars/version-5.x-sidebars.json
@@ -57,6 +57,7 @@
"devtools",
{
"type": "category",
+ "collapsible": true,
"label": "Navigators",
"items": [
"stack-navigator",
@@ -69,6 +70,7 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Hooks",
"items": [
"use-navigation",
@@ -86,6 +88,7 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Actions",
"items": [
"navigation-actions",
@@ -95,20 +98,12 @@
]
}
],
- "Build your own Navigator": [
- "custom-routers",
- "custom-navigators"
- ],
+ "Build your own Navigator": ["custom-routers", "custom-navigators"],
"Additional resources": [
"supported-react-native-versions",
"community-libraries-and-navigators",
"more-resources"
],
- "Meta": [
- "pitch",
- "alternatives",
- "used-by",
- "contributing"
- ]
+ "Meta": ["pitch", "alternatives", "used-by", "contributing"]
}
}
diff --git a/versioned_sidebars/version-6.x-sidebars.json b/versioned_sidebars/version-6.x-sidebars.json
index cafe58fe51f..84e8e49ef06 100644
--- a/versioned_sidebars/version-6.x-sidebars.json
+++ b/versioned_sidebars/version-6.x-sidebars.json
@@ -9,10 +9,7 @@
"header-buttons",
"nesting-navigators",
"navigation-lifecycle",
- "next-steps",
- "glossary-of-terms",
- "troubleshooting",
- "limitations"
+ "next-steps"
],
"Guides": [
"tab-based-navigation",
@@ -41,6 +38,7 @@
"typescript",
"redux-integration",
"MST-integration",
+ "troubleshooting",
"upgrading-from-5.x"
],
"Navigators": [
@@ -51,12 +49,7 @@
"material-bottom-tab-navigator",
"material-top-tab-navigator"
],
- "Libraries": [
- "devtools",
- "elements",
- "tab-view",
- "drawer-layout"
- ],
+ "Libraries": ["devtools", "elements", "tab-view", "drawer-layout"],
"API reference": [
"navigation-container",
"server-container",
@@ -71,6 +64,7 @@
"link",
{
"type": "category",
+ "collapsible": true,
"label": "Hooks",
"items": [
"use-navigation",
@@ -87,6 +81,7 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Actions",
"items": [
"navigation-actions",
@@ -96,17 +91,16 @@
]
}
],
- "Build your own Navigator": [
- "custom-routers",
- "custom-navigators"
- ],
+ "Build your own Navigator": ["custom-routers", "custom-navigators"],
"Additional resources": [
"migration-guides",
"navigation-solutions-and-community-libraries",
"more-resources"
],
"Meta": [
+ "glossary-of-terms",
"pitch",
+ "limitations",
"used-by",
"contributing"
]
diff --git a/versioned_sidebars/version-7.x-sidebars.json b/versioned_sidebars/version-7.x-sidebars.json
index ca65458cbc5..2467400dbfe 100644
--- a/versioned_sidebars/version-7.x-sidebars.json
+++ b/versioned_sidebars/version-7.x-sidebars.json
@@ -12,10 +12,9 @@
"next-steps"
],
"Guides": [
- "tab-based-navigation",
- "drawer-based-navigation",
"auth-flow",
"handling-safe-area",
+ "customizing-tabbar",
"hiding-tabbar-in-screens",
"status-bar",
"modal",
@@ -33,35 +32,26 @@
"screen-tracking",
"themes",
"state-persistence",
+ "combine-static-with-dynamic",
"testing",
"typescript",
- "redux-integration",
- "MST-integration",
"troubleshooting",
"upgrading-from-6.x"
],
- "Static configuration": [
- "static-api-reference",
- "static-typescript",
- "static-authentication",
- "static-combine-with-dynamic"
- ],
"Navigators": [
"stack-navigator",
"native-stack-navigator",
- "drawer-navigator",
"bottom-tab-navigator",
+ "native-bottom-tab-navigator",
+ "drawer-navigator",
"material-top-tab-navigator"
],
- "Libraries": [
- "devtools",
- "elements",
- "tab-view",
- "drawer-layout"
- ],
+ "Libraries": ["devtools", "elements", "tab-view", "drawer-layout"],
"API reference": [
+ "static-configuration",
"navigation-container",
"server-container",
+ "navigator",
"group",
"screen",
"screen-options",
@@ -73,6 +63,7 @@
"link",
{
"type": "category",
+ "collapsible": true,
"label": "Hooks",
"items": [
"use-navigation",
@@ -80,6 +71,8 @@
"use-navigation-state",
"use-focus-effect",
"use-is-focused",
+ "use-prevent-remove",
+ "use-route-path",
"use-link-to",
"use-link-props",
"use-link-builder",
@@ -89,6 +82,7 @@
},
{
"type": "category",
+ "collapsible": true,
"label": "Actions",
"items": [
"navigation-actions",
@@ -98,16 +92,15 @@
]
}
],
- "Build your own Navigator": [
- "custom-routers",
- "custom-navigators"
- ],
- "Additional resources": [
- "migration-guides",
- "navigation-solutions-and-community-libraries",
+ "Build your own Navigator": ["custom-routers", "custom-navigators"],
+ "Ecosystem": [
+ "community-solutions",
+ "community-navigators",
+ "community-libraries",
"more-resources"
],
"Meta": [
+ "migration-guides",
"glossary-of-terms",
"pitch",
"limitations",
diff --git a/versions.json b/versions.json
index eeee1e3bf0d..9aca05ea139 100644
--- a/versions.json
+++ b/versions.json
@@ -1,9 +1 @@
-[
- "7.x",
- "6.x",
- "5.x",
- "4.x",
- "3.x",
- "2.x",
- "1.x"
-]
+["7.x", "6.x", "5.x", "4.x", "3.x", "2.x", "1.x"]
diff --git a/yarn.lock b/yarn.lock
index ac228d70dc2..99dfa2460c5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -197,7 +197,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.4, @babel/code-frame@npm:^7.8.3":
+"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.8.3":
version: 7.23.4
resolution: "@babel/code-frame@npm:7.23.4"
dependencies:
@@ -207,114 +207,125 @@ __metadata:
languageName: node
linkType: hard
-"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/compat-data@npm:7.23.3"
- checksum: c6af331753c34ee8a5678bc94404320826cb56b1dda3efc1311ec8fb0774e78225132f3c1acc988440ace667f14a838e297a822692b95758aa63da406e1f97a1
+"@babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0":
+ version: 7.26.2
+ resolution: "@babel/code-frame@npm:7.26.2"
+ dependencies:
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ js-tokens: "npm:^4.0.0"
+ picocolors: "npm:^1.0.0"
+ checksum: 7d79621a6849183c415486af99b1a20b84737e8c11cd55b6544f688c51ce1fd710e6d869c3dd21232023da272a79b91efb3e83b5bc2dc65c1187c5fcd1b72ea8
+ languageName: node
+ linkType: hard
+
+"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.9, @babel/compat-data@npm:^7.26.0":
+ version: 7.26.2
+ resolution: "@babel/compat-data@npm:7.26.2"
+ checksum: c9b5f3724828d17f728a778f9d66c19b55c018d0d76de6d731178cca64f182c22b71400a73bf2b65dcc4fcfe52b630088a94d5902911b54206aa90e3ffe07d12
languageName: node
linkType: hard
-"@babel/core@npm:^7.19.6, @babel/core@npm:^7.22.9":
- version: 7.23.3
- resolution: "@babel/core@npm:7.23.3"
+"@babel/core@npm:^7.21.3, @babel/core@npm:^7.25.9":
+ version: 7.26.0
+ resolution: "@babel/core@npm:7.26.0"
dependencies:
"@ampproject/remapping": "npm:^2.2.0"
- "@babel/code-frame": "npm:^7.22.13"
- "@babel/generator": "npm:^7.23.3"
- "@babel/helper-compilation-targets": "npm:^7.22.15"
- "@babel/helper-module-transforms": "npm:^7.23.3"
- "@babel/helpers": "npm:^7.23.2"
- "@babel/parser": "npm:^7.23.3"
- "@babel/template": "npm:^7.22.15"
- "@babel/traverse": "npm:^7.23.3"
- "@babel/types": "npm:^7.23.3"
+ "@babel/code-frame": "npm:^7.26.0"
+ "@babel/generator": "npm:^7.26.0"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-module-transforms": "npm:^7.26.0"
+ "@babel/helpers": "npm:^7.26.0"
+ "@babel/parser": "npm:^7.26.0"
+ "@babel/template": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.26.0"
convert-source-map: "npm:^2.0.0"
debug: "npm:^4.1.0"
gensync: "npm:^1.0.0-beta.2"
json5: "npm:^2.2.3"
semver: "npm:^6.3.1"
- checksum: 08d43b749e24052d12713a7fb1f0c0d1275d4fb056d00846faeb8da79ecf6d0ba91a11b6afec407b8b0f9388d00e2c2f485f282bef0ade4d6d0a17de191a4287
+ checksum: 91de73a7ff5c4049fbc747930aa039300e4d2670c2a91f5aa622f1b4868600fc89b01b6278385fbcd46f9574186fa3d9b376a9e7538e50f8d118ec13cfbcb63e
languageName: node
linkType: hard
-"@babel/generator@npm:^7.22.9, @babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.4":
- version: 7.23.4
- resolution: "@babel/generator@npm:7.23.4"
+"@babel/generator@npm:^7.25.9, @babel/generator@npm:^7.26.0":
+ version: 7.26.2
+ resolution: "@babel/generator@npm:7.26.2"
dependencies:
- "@babel/types": "npm:^7.23.4"
- "@jridgewell/gen-mapping": "npm:^0.3.2"
- "@jridgewell/trace-mapping": "npm:^0.3.17"
- jsesc: "npm:^2.5.1"
- checksum: 79b87ef49c4af1b4356b2fcab80ed92dfcad7927c3d6d89c4f749fd947768de3ec129467fb8eee0fe53cf8fc38b4d34d44487f714a9c23bee981c9cba3a670e4
+ "@babel/parser": "npm:^7.26.2"
+ "@babel/types": "npm:^7.26.0"
+ "@jridgewell/gen-mapping": "npm:^0.3.5"
+ "@jridgewell/trace-mapping": "npm:^0.3.25"
+ jsesc: "npm:^3.0.2"
+ checksum: 167ebce8977142f5012fad6bd91da51ac52bcd752f2261a54b7ab605d928aebe57e21636cdd2a9c7757e552652c68d9fcb5d40b06fcb66e02d9ee7526e118a5c
languageName: node
linkType: hard
-"@babel/helper-annotate-as-pure@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/helper-annotate-as-pure@npm:7.22.5"
+"@babel/helper-annotate-as-pure@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-annotate-as-pure@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.5"
- checksum: 5a80dc364ddda26b334bbbc0f6426cab647381555ef7d0cd32eb284e35b867c012ce6ce7d52a64672ed71383099c99d32765b3d260626527bb0e3470b0f58e45
+ "@babel/types": "npm:^7.25.9"
+ checksum: 095b6ba50489d797733abebc4596a81918316a99e3632755c9f02508882912b00c2ae5e468532a25a5c2108d109ddbe9b7da78333ee7cc13817fc50c00cf06fe
languageName: node
linkType: hard
-"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.15":
- version: 7.22.15
- resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15"
+"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.15"
- checksum: 2535e3824ca6337f65786bbac98e562f71699f25532cecd196f027d7698b4967a96953d64e36567956658ad1a05ccbdc62d1ba79ee751c79f4f1d2d3ecc2e01c
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: a6068bb813e7f72d12b72edeecb99167f60cd7964cacedfb60e01fff5e7bed4a5a7f4f7414de7cf352a1b71487df5f8dab8c2b5230de4ad5aea16adf32e14219
languageName: node
linkType: hard
-"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.6":
- version: 7.22.15
- resolution: "@babel/helper-compilation-targets@npm:7.22.15"
+"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-compilation-targets@npm:7.25.9"
dependencies:
- "@babel/compat-data": "npm:^7.22.9"
- "@babel/helper-validator-option": "npm:^7.22.15"
- browserslist: "npm:^4.21.9"
+ "@babel/compat-data": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ browserslist: "npm:^4.24.0"
lru-cache: "npm:^5.1.1"
semver: "npm:^6.3.1"
- checksum: 45b9286861296e890f674a3abb199efea14a962a27d9b8adeb44970a9fd5c54e73a9e342e8414d2851cf4f98d5994537352fbce7b05ade32e9849bbd327f9ff1
+ checksum: a6b26a1e4222e69ef8e62ee19374308f060b007828bc11c65025ecc9e814aba21ff2175d6d3f8bf53c863edd728ee8f94ba7870f8f90a37d39552ad9933a8aaa
languageName: node
linkType: hard
-"@babel/helper-create-class-features-plugin@npm:^7.22.15":
- version: 7.22.15
- resolution: "@babel/helper-create-class-features-plugin@npm:7.22.15"
+"@babel/helper-create-class-features-plugin@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-create-class-features-plugin@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-environment-visitor": "npm:^7.22.5"
- "@babel/helper-function-name": "npm:^7.22.5"
- "@babel/helper-member-expression-to-functions": "npm:^7.22.15"
- "@babel/helper-optimise-call-expression": "npm:^7.22.5"
- "@babel/helper-replace-supers": "npm:^7.22.9"
- "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5"
- "@babel/helper-split-export-declaration": "npm:^7.22.6"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-member-expression-to-functions": "npm:^7.25.9"
+ "@babel/helper-optimise-call-expression": "npm:^7.25.9"
+ "@babel/helper-replace-supers": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 2ae5759fe8845fda99b34f2ba6cd0794fc860213d14c93a87aa9180960252bce621157a79c373b7fbb423b25a55fb0e20eae0d5f8e4ad5ef22dc70e7c2af3805
+ checksum: b2bdd39f38056a76b9ba00ec5b209dd84f5c5ebd998d0f4033cf0e73d5f2c357fbb49d1ce52db77a2709fb29ee22321f84a5734dc9914849bdfee9ad12ce8caf
languageName: node
linkType: hard
-"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5":
- version: 7.22.15
- resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15"
+"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- regexpu-core: "npm:^5.3.1"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ regexpu-core: "npm:^6.1.1"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 8eba4c1b7b94a83e7a82df5c3e504584ff0ba6ab8710a67ecc2c434a7fb841a29c2f5c94d2de51f25446119a1df538fa90b37bd570db22ddd5e7147fe98277c6
+ checksum: 3adc60a758febbf07d65a15eaccab1f7b9fcc55e7141e59122f13c9f81fc0d1cce4525b7f4af50285d27c93b34c859fd2c39c39820c5fb92211898c3bbdc77ef
languageName: node
linkType: hard
-"@babel/helper-define-polyfill-provider@npm:^0.4.3":
- version: 0.4.3
- resolution: "@babel/helper-define-polyfill-provider@npm:0.4.3"
+"@babel/helper-define-polyfill-provider@npm:^0.6.2":
+ version: 0.6.2
+ resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2"
dependencies:
"@babel/helper-compilation-targets": "npm:^7.22.6"
"@babel/helper-plugin-utils": "npm:^7.22.5"
@@ -323,135 +334,109 @@ __metadata:
resolve: "npm:^1.14.2"
peerDependencies:
"@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0
- checksum: 0007035157e0d32ee9cb4ca319b89d6f3705523383efe52a59eb3d4dfa2ed08c5147e49c10a6e6d69c15221d89c76c8e5875475d6710fb44a5c37b8e69388e40
- languageName: node
- linkType: hard
-
-"@babel/helper-environment-visitor@npm:^7.22.20, @babel/helper-environment-visitor@npm:^7.22.5":
- version: 7.22.20
- resolution: "@babel/helper-environment-visitor@npm:7.22.20"
- checksum: e762c2d8f5d423af89bd7ae9abe35bd4836d2eb401af868a63bbb63220c513c783e25ef001019418560b3fdc6d9a6fb67e6c0b650bcdeb3a2ac44b5c3d2bdd94
- languageName: node
- linkType: hard
-
-"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0":
- version: 7.23.0
- resolution: "@babel/helper-function-name@npm:7.23.0"
- dependencies:
- "@babel/template": "npm:^7.22.15"
- "@babel/types": "npm:^7.23.0"
- checksum: d771dd1f3222b120518176733c52b7cadac1c256ff49b1889dbbe5e3fed81db855b8cc4e40d949c9d3eae0e795e8229c1c8c24c0e83f27cfa6ee3766696c6428
- languageName: node
- linkType: hard
-
-"@babel/helper-hoist-variables@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/helper-hoist-variables@npm:7.22.5"
- dependencies:
- "@babel/types": "npm:^7.22.5"
- checksum: 60a3077f756a1cd9f14eb89f0037f487d81ede2b7cfe652ea6869cd4ec4c782b0fb1de01b8494b9a2d2050e3d154d7d5ad3be24806790acfb8cbe2073bf1e208
+ checksum: f777fe0ee1e467fdaaac059c39ed203bdc94ef2465fb873316e9e1acfc511a276263724b061e3b0af2f6d7ad3ff174f2bb368fde236a860e0f650fda43d7e022
languageName: node
linkType: hard
-"@babel/helper-member-expression-to-functions@npm:^7.22.15":
- version: 7.23.0
- resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0"
+"@babel/helper-member-expression-to-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-member-expression-to-functions@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.23.0"
- checksum: b810daddf093ffd0802f1429052349ed9ea08ef7d0c56da34ffbcdecbdafac86f95bdea2fe30e0e0e629febc7dd41b56cb5eacc10d1a44336d37b755dac31fa4
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: e08c7616f111e1fb56f398365e78858e26e466d4ac46dff25921adc5ccae9b232f66e952a2f4162bbe336627ba336c7fd9eca4835b6548935973d3380d77eaff
languageName: node
linkType: hard
-"@babel/helper-module-imports@npm:^7.22.15":
- version: 7.22.15
- resolution: "@babel/helper-module-imports@npm:7.22.15"
+"@babel/helper-module-imports@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-module-imports@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.15"
- checksum: 4e0d7fc36d02c1b8c8b3006dfbfeedf7a367d3334a04934255de5128115ea0bafdeb3e5736a2559917f0653e4e437400d54542da0468e08d3cbc86d3bbfa8f30
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 078d3c2b45d1f97ffe6bb47f61961be4785d2342a4156d8b42c92ee4e1b7b9e365655dd6cb25329e8fe1a675c91eeac7e3d04f0c518b67e417e29d6e27b6aa70
languageName: node
linkType: hard
-"@babel/helper-module-transforms@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/helper-module-transforms@npm:7.23.3"
+"@babel/helper-module-transforms@npm:^7.25.9, @babel/helper-module-transforms@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/helper-module-transforms@npm:7.26.0"
dependencies:
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-module-imports": "npm:^7.22.15"
- "@babel/helper-simple-access": "npm:^7.22.5"
- "@babel/helper-split-export-declaration": "npm:^7.22.6"
- "@babel/helper-validator-identifier": "npm:^7.22.20"
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 211e1399d0c4993671e8e5c2b25383f08bee40004ace5404ed4065f0e9258cc85d99c1b82fd456c030ce5cfd4d8f310355b54ef35de9924eabfc3dff1331d946
+ checksum: ee111b68a5933481d76633dad9cdab30c41df4479f0e5e1cc4756dc9447c1afd2c9473b5ba006362e35b17f4ebddd5fca090233bef8dfc84dca9d9127e56ec3a
languageName: node
linkType: hard
-"@babel/helper-optimise-call-expression@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/helper-optimise-call-expression@npm:7.22.5"
+"@babel/helper-optimise-call-expression@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-optimise-call-expression@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.5"
- checksum: 31b41a764fc3c585196cf5b776b70cf4705c132e4ce9723f39871f215f2ddbfb2e28a62f9917610f67c8216c1080482b9b05f65dd195dae2a52cef461f2ac7b8
+ "@babel/types": "npm:^7.25.9"
+ checksum: 90203e6607edeadd2a154940803fd616c0ed92c1013d6774c4b8eb491f1a5a3448b68faae6268141caa5c456e55e3ee49a4ed2bd7ddaf2365daea321c435914c
languageName: node
linkType: hard
-"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3":
+"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0":
version: 7.22.5
resolution: "@babel/helper-plugin-utils@npm:7.22.5"
checksum: d2c4bfe2fa91058bcdee4f4e57a3f4933aed7af843acfd169cd6179fab8d13c1d636474ecabb2af107dc77462c7e893199aa26632bac1c6d7e025a17cbb9d20d
languageName: node
linkType: hard
-"@babel/helper-remap-async-to-generator@npm:^7.22.20":
- version: 7.22.20
- resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20"
- dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-wrap-function": "npm:^7.22.20"
- peerDependencies:
- "@babel/core": ^7.0.0
- checksum: aa93aa74250b636d477e8d863fbe59d4071f8c2654841b7ac608909e480c1cf3ff7d7af5a4038568829ad09d810bb681668cbe497d9c89ba5c352793dc9edf1e
+"@babel/helper-plugin-utils@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-plugin-utils@npm:7.25.9"
+ checksum: 483066a1ba36ff16c0116cd24f93de05de746a603a777cd695ac7a1b034928a65a4ecb35f255761ca56626435d7abdb73219eba196f9aa83b6c3c3169325599d
languageName: node
linkType: hard
-"@babel/helper-replace-supers@npm:^7.22.20, @babel/helper-replace-supers@npm:^7.22.9":
- version: 7.22.20
- resolution: "@babel/helper-replace-supers@npm:7.22.20"
+"@babel/helper-remap-async-to-generator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-remap-async-to-generator@npm:7.25.9"
dependencies:
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-member-expression-to-functions": "npm:^7.22.15"
- "@babel/helper-optimise-call-expression": "npm:^7.22.5"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-wrap-function": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 6b0858811ad46873817c90c805015d63300e003c5a85c147a17d9845fa2558a02047c3cc1f07767af59014b2dd0fa75b503e5bc36e917f360e9b67bb6f1e79f4
+ checksum: 6798b562f2788210980f29c5ee96056d90dc73458c88af5bd32f9c82e28e01975588aa2a57bb866c35556bd9b76bac937e824ee63ba472b6430224b91b4879e9
languageName: node
linkType: hard
-"@babel/helper-simple-access@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/helper-simple-access@npm:7.22.5"
+"@babel/helper-replace-supers@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-replace-supers@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.5"
- checksum: f0cf81a30ba3d09a625fd50e5a9069e575c5b6719234e04ee74247057f8104beca89ed03e9217b6e9b0493434cedc18c5ecca4cea6244990836f1f893e140369
+ "@babel/helper-member-expression-to-functions": "npm:^7.25.9"
+ "@babel/helper-optimise-call-expression": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 0b40d7d2925bd3ba4223b3519e2e4d2456d471ad69aa458f1c1d1783c80b522c61f8237d3a52afc9e47c7174129bbba650df06393a6787d5722f2ec7f223c3f4
languageName: node
linkType: hard
-"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5"
+"@babel/helper-simple-access@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-simple-access@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.5"
- checksum: ab7fa2aa709ab49bb8cd86515a1e715a3108c4bb9a616965ba76b43dc346dee66d1004ccf4d222b596b6224e43e04cbc5c3a34459501b388451f8c589fbc3691
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 3f1bcdb88ee3883ccf86959869a867f6bbf8c4737cd44fb9f799c38e54f67474590bc66802500ae9fe18161792875b2cfb7ec15673f48ed6c8663f6d09686ca8
languageName: node
linkType: hard
-"@babel/helper-split-export-declaration@npm:^7.22.6":
- version: 7.22.6
- resolution: "@babel/helper-split-export-declaration@npm:7.22.6"
+"@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.9"
dependencies:
- "@babel/types": "npm:^7.22.5"
- checksum: d83e4b623eaa9622c267d3c83583b72f3aac567dc393dda18e559d79187961cb29ae9c57b2664137fc3d19508370b12ec6a81d28af73a50e0846819cb21c6e44
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 09ace0c6156961624ac9524329ce7f45350bab94bbe24335cbe0da7dfaa1448e658771831983cb83fe91cf6635b15d0a3cab57c03b92657480bfb49fb56dd184
languageName: node
linkType: hard
@@ -462,6 +447,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-string-parser@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-string-parser@npm:7.25.9"
+ checksum: 7244b45d8e65f6b4338a6a68a8556f2cb161b782343e97281a5f2b9b93e420cad0d9f5773a59d79f61d0c448913d06f6a2358a87f2e203cf112e3c5b53522ee6
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-identifier@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-validator-identifier@npm:7.22.20"
@@ -469,32 +461,38 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-validator-option@npm:^7.22.15":
- version: 7.22.15
- resolution: "@babel/helper-validator-option@npm:7.22.15"
- checksum: e9661bf80ba18e2dd978217b350fb07298e57ac417f4f1ab9fa011505e20e4857f2c3b4b538473516a9dc03af5ce3a831e5ed973311c28326f4c330b6be981c2
+"@babel/helper-validator-identifier@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-validator-identifier@npm:7.25.9"
+ checksum: 4fc6f830177b7b7e887ad3277ddb3b91d81e6c4a24151540d9d1023e8dc6b1c0505f0f0628ae653601eb4388a8db45c1c14b2c07a9173837aef7e4116456259d
languageName: node
linkType: hard
-"@babel/helper-wrap-function@npm:^7.22.20":
- version: 7.22.20
- resolution: "@babel/helper-wrap-function@npm:7.22.20"
+"@babel/helper-validator-option@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-validator-option@npm:7.25.9"
+ checksum: 27fb195d14c7dcb07f14e58fe77c44eea19a6a40a74472ec05c441478fa0bb49fa1c32b2d64be7a38870ee48ef6601bdebe98d512f0253aea0b39756c4014f3e
+ languageName: node
+ linkType: hard
+
+"@babel/helper-wrap-function@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-wrap-function@npm:7.25.9"
dependencies:
- "@babel/helper-function-name": "npm:^7.22.5"
- "@babel/template": "npm:^7.22.15"
- "@babel/types": "npm:^7.22.19"
- checksum: 97b5f42ff4d305318ff2f99a5f59d3e97feff478333b2d893c4f85456d3c66372070f71d7bf9141f598c8cf2741c49a15918193633c427a88d170d98eb8c46eb
+ "@babel/template": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: b6627d83291e7b80df020f8ee2890c52b8d49272962cac0114ef90f189889c90f1027985873d1b5261a4e986e109b2754292dc112392f0b1fcbfc91cc08bd003
languageName: node
linkType: hard
-"@babel/helpers@npm:^7.23.2":
- version: 7.23.4
- resolution: "@babel/helpers@npm:7.23.4"
+"@babel/helpers@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/helpers@npm:7.26.0"
dependencies:
- "@babel/template": "npm:^7.22.15"
- "@babel/traverse": "npm:^7.23.4"
- "@babel/types": "npm:^7.23.4"
- checksum: 6bb552b3de530f5eaae99f5410826b5877bae38ccd95cb5809c9a0cef99bcdb9f5db373309c1cf873f5d68927993515323985bac0ff1b811f2437f2e3ae994b8
+ "@babel/template": "npm:^7.25.9"
+ "@babel/types": "npm:^7.26.0"
+ checksum: 343333cced6946fe46617690a1d0789346960910225ce359021a88a60a65bc0d791f0c5d240c0ed46cf8cc63b5fd7df52734ff14e43b9c32feae2b61b1647097
languageName: node
linkType: hard
@@ -509,90 +507,82 @@ __metadata:
languageName: node
linkType: hard
-"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4":
- version: 7.23.4
- resolution: "@babel/parser@npm:7.23.4"
+"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.2":
+ version: 7.26.2
+ resolution: "@babel/parser@npm:7.26.2"
+ dependencies:
+ "@babel/types": "npm:^7.26.0"
bin:
parser: ./bin/babel-parser.js
- checksum: 9115cd9c5855a6c7a8dd246938b1316dc1014ad36e01240c1e94ada63218ca39aa63d953d1bff8074a2737933448bc50736eb3da52ffc5c11a256c66d0accc2b
+ checksum: 751a743087b3a9172a7599f1421830d44c38f065ef781588d2bfb1c98f9b461719a226feb13c868d7a284783eee120c88ea522593118f2668f46ebfb1105c4d7
languageName: node
linkType: hard
-"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.23.3"
+"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 356a4e9fc52d7ca761ce6857fc58e2295c2785d22565760e6a5680be86c6e5883ab86e0ba25ef572882c01713d3a31ae6cfa3e3222cdb95e6026671dab1fa415
+ checksum: 7aab47fcbb8c1ddc195a3cd66609edcad54c5022f018db7de40185f0182950389690e953e952f117a1737b72f665ff02ad30de6c02b49b97f1d8f4ccdffedc34
languageName: node
linkType: hard
-"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.23.3"
+"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5"
- "@babel/plugin-transform-optional-chaining": "npm:^7.23.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
- "@babel/core": ^7.13.0
- checksum: a8785f099d55ca71ed89815e0f3a636a80c16031f80934cfec17c928d096ee0798964733320c8b145ef36ba429c5e19d5107b06231e0ab6777cfb0f01adfdc23
+ "@babel/core": ^7.0.0
+ checksum: 3a652b3574ca62775c5f101f8457950edc540c3581226579125da535d67765f41ad7f0e6327f8efeb2540a5dad5bb0c60a89fb934af3f67472e73fb63612d004
languageName: node
linkType: hard
-"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.3"
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.9"
dependencies:
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 0f43b74741d50e637ba4dcef2786621126fe4da6ccf4ee2e94423ee23f6a04ecd91d458e59764c43e4968be139e5197ee43be8a2fea2c09f0b202a3391e548cc
+ checksum: 18fc9004104a150f9f5da9f3307f361bc3104d16778bb593b7523d5110f04a8df19a2587e6bdd5e726fb1d397191add45223f4f731bb556c33f14f2779d596e8
languageName: node
linkType: hard
-"@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2":
- version: 7.21.0-placeholder-for-preset-env.2
- resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: e605e0070da087f6c35579499e65801179a521b6842c15181a1e305c04fded2393f11c1efd09b087be7f8b083d1b75e8f3efcbc1292b4f60d3369e14812cff63
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-async-generators@npm:^7.8.4":
- version: 7.8.4
- resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4"
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.0"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ "@babel/plugin-transform-optional-chaining": "npm:^7.25.9"
peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8
+ "@babel/core": ^7.13.0
+ checksum: 3f6c8781a2f7aa1791a31d2242399ca884df2ab944f90c020b6f112fb19f05fa6dad5be143d274dad1377e40415b63d24d5489faf5060b9c4a99e55d8f0c317c
languageName: node
linkType: hard
-"@babel/plugin-syntax-class-properties@npm:^7.12.13":
- version: 7.12.13
- resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13"
+"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.12.13"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120
+ "@babel/core": ^7.0.0
+ checksum: 02b365f0cc4df8b8b811c68697c93476da387841e5f153fe42766f34241b685503ea51110d5ed6df7132759820b93e48d9fa3743cffc091eed97c19f7e5fe272
languageName: node
linkType: hard
-"@babel/plugin-syntax-class-static-block@npm:^7.14.5":
- version: 7.14.5
- resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.14.5"
+"@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2":
+ version: 7.21.0-placeholder-for-preset-env.2
+ resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 4464bf9115f4a2d02ce1454411baf9cfb665af1da53709c5c56953e5e2913745b0fcce82982a00463d6facbdd93445c691024e310b91431a1e2f024b158f6371
+ checksum: e605e0070da087f6c35579499e65801179a521b6842c15181a1e305c04fded2393f11c1efd09b087be7f8b083d1b75e8f3efcbc1292b4f60d3369e14812cff63
languageName: node
linkType: hard
@@ -607,168 +597,47 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3":
- version: 7.8.3
- resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.3"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 5100d658ba563829700cd8d001ddc09f4c0187b1a13de300d729c5b3e87503f75a6d6c99c1794182f7f1a9f546ee009df4f15a0ce36376e206ed0012fa7cdc24
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-import-assertions@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-syntax-import-assertions@npm:7.23.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 7db8b59f75667bada2293353bb66b9d5651a673b22c72f47da9f5c46e719142481601b745f9822212fd7522f92e26e8576af37116f85dae1b5e5967f80d0faab
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-import-attributes@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-syntax-import-attributes@npm:7.23.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 99b40d33d79205a8e04bb5dea56fd72906ffc317513b20ca7319e7683e18fce8ea2eea5e9171056f92b979dc0ab1e31b2cb5171177a5ba61e05b54fe7850a606
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-import-meta@npm:^7.10.4":
- version: 7.10.4
- resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.10.4"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-json-strings@npm:^7.8.3":
- version: 7.8.3
- resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.0"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-jsx@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-syntax-jsx@npm:7.23.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 563bb7599b868773f1c7c1d441ecc9bc53aeb7832775da36752c926fc402a1fa5421505b39e724f71eb217c13e4b93117e081cac39723b0e11dac4c897f33c3e
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4":
- version: 7.10.4
- resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.10.4"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3":
- version: 7.8.3
- resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.0"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-numeric-separator@npm:^7.10.4":
- version: 7.10.4
- resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.10.4"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3":
- version: 7.8.3
- resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.0"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3":
- version: 7.8.3
- resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3"
+"@babel/plugin-syntax-import-assertions@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-syntax-import-assertions@npm:7.26.0"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.0"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af
+ checksum: 525b174e60b210d96c1744c1575fc2ddedcc43a479cba64a5344cf77bd0541754fc58120b5a11ff832ba098437bb05aa80900d1f49bb3d888c5e349a4a3a356e
languageName: node
linkType: hard
-"@babel/plugin-syntax-optional-chaining@npm:^7.8.3":
- version: 7.8.3
- resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3"
+"@babel/plugin-syntax-import-attributes@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-syntax-import-attributes@npm:7.26.0"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.8.0"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81
+ checksum: e594c185b12bfe0bbe7ca78dfeebe870e6d569a12128cac86f3164a075fe0ff70e25ddbd97fd0782906b91f65560c9dc6957716b7b4a68aba2516c9b7455e352
languageName: node
linkType: hard
-"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5":
- version: 7.14.5
- resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5"
+"@babel/plugin-syntax-jsx@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-syntax-jsx@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.14.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 69822772561706c87f0a65bc92d0772cea74d6bc0911537904a676d5ff496a6d3ac4e05a166d8125fce4a16605bace141afc3611074e170a994e66e5397787f3
+ checksum: d56597aff4df39d3decda50193b6dfbe596ca53f437ff2934622ce19a743bf7f43492d3fb3308b0289f5cee2b825d99ceb56526a2b9e7b68bf04901546c5618c
languageName: node
linkType: hard
-"@babel/plugin-syntax-top-level-await@npm:^7.14.5":
- version: 7.14.5
- resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5"
+"@babel/plugin-syntax-typescript@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-syntax-typescript@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.14.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f
- languageName: node
- linkType: hard
-
-"@babel/plugin-syntax-typescript@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-syntax-typescript@npm:7.23.3"
- dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- peerDependencies:
- "@babel/core": ^7.0.0-0
- checksum: 4d6e9cdb9d0bfb9bd9b220fc951d937fce2ca69135ec121153572cebe81d86abc9a489208d6b69ee5f10cadcaeffa10d0425340a5029e40e14a6025021b90948
+ checksum: 5192ebe11bd46aea68b7a60fd9555465c59af7e279e71126788e59121b86e00b505816685ab4782abe159232b0f73854e804b54449820b0d950b397ee158caa2
languageName: node
linkType: hard
@@ -784,763 +653,762 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-arrow-functions@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-arrow-functions@npm:7.23.3"
+"@babel/plugin-transform-arrow-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: b128315c058f5728d29b0b78723659b11de88247ea4d0388f0b935cddf60a80c40b9067acf45cbbe055bd796928faef152a09d9e4a0695465aca4394d9f109ca
+ checksum: 851fef9f58be60a80f46cc0ce1e46a6f7346a6f9d50fa9e0fa79d46ec205320069d0cc157db213e2bea88ef5b7d9bd7618bb83f0b1996a836e2426c3a3a1f622
languageName: node
linkType: hard
-"@babel/plugin-transform-async-generator-functions@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.4"
+"@babel/plugin-transform-async-generator-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.9"
dependencies:
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-remap-async-to-generator": "npm:^7.22.20"
- "@babel/plugin-syntax-async-generators": "npm:^7.8.4"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-remap-async-to-generator": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: f2eef4de609975a3f7da7832576b5ffc93e43c80f87e1a99e886b0f8591096cfc4c37e2d5f52fdeaa2a9c09a25a59f3e621159abaca75d3193922a5c0e4cbe0c
+ checksum: e3fcb9fc3d6ab6cbd4fcd956b48c17b5e92fe177553df266ffcd2b2c1f2f758b893e51b638e77ed867941e0436487d2b8b505908d615c41799241699b520dec6
languageName: node
linkType: hard
-"@babel/plugin-transform-async-to-generator@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-async-to-generator@npm:7.23.3"
+"@babel/plugin-transform-async-to-generator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.9"
dependencies:
- "@babel/helper-module-imports": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-remap-async-to-generator": "npm:^7.22.20"
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-remap-async-to-generator": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: da3ffd413eef02a8e2cfee3e0bb0d5fc0fcb795c187bc14a5a8e8874cdbdc43bbf00089c587412d7752d97efc5967c3c18ff5398e3017b9a14a06126f017e7e9
+ checksum: c443d9e462ddef733ae56360064f32fc800105803d892e4ff32d7d6a6922b3765fa97b9ddc9f7f1d3f9d8c2d95721d85bef9dbf507804214c6cf6466b105c168
languageName: node
linkType: hard
-"@babel/plugin-transform-block-scoped-functions@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.23.3"
+"@babel/plugin-transform-block-scoped-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 82c12a11277528184a979163de7189ceb00129f60dd930b0d5313454310bf71205f302fb2bf0430247161c8a22aaa9fb9eec1459f9f7468206422c191978fd59
+ checksum: e92ba0e3d72c038513844d8fca1cc8437dcb35cd42778e97fd03cb8303380b201468611e7ecfdcae3de33473b2679fe2de1552c5f925d112c5693425cf851f10
languageName: node
linkType: hard
-"@babel/plugin-transform-block-scoping@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-block-scoping@npm:7.23.4"
+"@babel/plugin-transform-block-scoping@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-block-scoping@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 83006804dddf980ab1bcd6d67bc381e24b58c776507c34f990468f820d0da71dba3697355ca4856532fa2eeb2a1e3e73c780f03760b5507a511cbedb0308e276
+ checksum: a76e30becb6c75b4d87a2cd53556fddb7c88ddd56bfadb965287fd944810ac159aa8eb5705366fc37336041f63154ed9fab3862fb10482a45bf5ede63fd55fda
languageName: node
linkType: hard
-"@babel/plugin-transform-class-properties@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-class-properties@npm:7.23.3"
+"@babel/plugin-transform-class-properties@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-class-properties@npm:7.25.9"
dependencies:
- "@babel/helper-create-class-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: bca30d576f539eef216494b56d610f1a64aa9375de4134bc021d9660f1fa735b1d7cc413029f22abc0b7cb737e3a57935c8ae9d8bd1730921ccb1deebce51bfd
+ checksum: f0603b6bd34d8ba62c03fc0572cb8bbc75874d097ac20cc7c5379e001081210a84dba1749e7123fca43b978382f605bb9973c99caf2c5b4c492d5c0a4a441150
languageName: node
linkType: hard
-"@babel/plugin-transform-class-static-block@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-class-static-block@npm:7.23.4"
+"@babel/plugin-transform-class-static-block@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-transform-class-static-block@npm:7.26.0"
dependencies:
- "@babel/helper-create-class-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-class-static-block": "npm:^7.14.5"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.12.0
- checksum: fdca96640ef29d8641a7f8de106f65f18871b38cc01c0f7b696d2b49c76b77816b30a812c08e759d06dd10b4d9b3af6b5e4ac22a2017a88c4077972224b77ab0
+ checksum: cdcf5545ae6514ed75fbd73cccfa209c6a5dfdf0c2bb7bb62c0fb4ec334a32281bcf1bc16ace494d9dbe93feb8bdc0bd3cf9d9ccb6316e634a67056fa13b741b
languageName: node
linkType: hard
-"@babel/plugin-transform-classes@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-classes@npm:7.23.3"
+"@babel/plugin-transform-classes@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-classes@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-compilation-targets": "npm:^7.22.15"
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-function-name": "npm:^7.23.0"
- "@babel/helper-optimise-call-expression": "npm:^7.22.5"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-replace-supers": "npm:^7.22.20"
- "@babel/helper-split-export-declaration": "npm:^7.22.6"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-replace-supers": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
globals: "npm:^11.1.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 88bfd332db0ba5cbfb8557a2ba5a7185151aebc9cfe3035b014aa6d795556acbe672bb8c78da3c9fd1d23f55a333d14b5daa127ef037f5ced5198b6d79a146d6
+ checksum: 02742ea7cd25be286c982e672619effca528d7a931626a6f3d6cea11852951b7ee973276127eaf6418ac0e18c4d749a16b520709c707e86a67012bd23ff2927d
languageName: node
linkType: hard
-"@babel/plugin-transform-computed-properties@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-computed-properties@npm:7.23.3"
+"@babel/plugin-transform-computed-properties@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-computed-properties@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/template": "npm:^7.22.15"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/template": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 3ca8a006f8e652b58c21ecb84df1d01a73f0a96b1d216fd09a890b235dd90cb966b152b603b88f7e850ae238644b1636ce5c30b7c029c0934b43383932372e4a
+ checksum: 948c0ae3ce0ba2375241d122a9bc7cda4a7ac8110bd8a62cd804bc46a5fdb7a7a42c7799c4cd972e14e0a579d2bd0999b92e53177b73f240bb0d4b09972c758b
languageName: node
linkType: hard
-"@babel/plugin-transform-destructuring@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-destructuring@npm:7.23.3"
+"@babel/plugin-transform-destructuring@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-destructuring@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 717e9a62c1b0c93c507f87b4eaf839ec08d3c3147f14d74ae240d8749488d9762a8b3950132be620a069bde70f4b3e4ee9867b226c973fcc40f3cdec975cde71
+ checksum: 7beec5fda665d108f69d5023aa7c298a1e566b973dd41290faa18aeea70f6f571295c1ece0a058f3ceb6c6c96de76de7cd34f5a227fbf09a1b8d8a735d28ca49
languageName: node
linkType: hard
-"@babel/plugin-transform-dotall-regex@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-dotall-regex@npm:7.23.3"
+"@babel/plugin-transform-dotall-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.9"
dependencies:
- "@babel/helper-create-regexp-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 6c89286d1277c2a63802a453c797c87c1203f89e4c25115f7b6620f5fce15d8c8d37af613222f6aa497aa98773577a6ec8752e79e13d59bc5429270677ea010b
+ checksum: 7c3471ae5cf7521fd8da5b03e137e8d3733fc5ee4524ce01fb0c812f0bb77cb2c9657bc8a6253186be3a15bb4caa8974993c7ddc067f554ecc6a026f0a3b5e12
languageName: node
linkType: hard
-"@babel/plugin-transform-duplicate-keys@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-duplicate-keys@npm:7.23.3"
+"@babel/plugin-transform-duplicate-keys@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 7e2640e4e6adccd5e7b0615b6e9239d7c98363e21c52086ea13759dfa11cf7159b255fc5331c2de435639ea8eb6acefae115ae0d797a3d19d12587652f8052a5
+ checksum: d0c74894b9bf6ff2a04189afffb9cd43d87ebd7b7943e51a827c92d2aaa40fa89ac81565a2fd6fbeabf9e38413a9264c45862eee2b017f1d49046cc3c8ff06b4
languageName: node
linkType: hard
-"@babel/plugin-transform-dynamic-import@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-dynamic-import@npm:7.23.4"
+"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: a8039a6d2b90e011c7b30975edee47b5b1097cf3c2f95ec1f5ddd029898d783a995f55f7d6eb8d6bb8873c060fb64f9f1ccba938dfe22d118d09cf68e0cd3bf6
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-dynamic-import@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 19ae4a4a2ca86d35224734c41c48b2aa6a13139f3cfa1cbd18c0e65e461de8b65687dec7e52b7a72bb49db04465394c776aa1b13a2af5dc975b2a0cde3dcab67
+ checksum: 5e643a8209072b668350f5788f23c64e9124f81f958b595c80fecca6561086d8ef346c04391b9e5e4cad8b8cbe22c258f0cd5f4ea89b97e74438e7d1abfd98cf
languageName: node
linkType: hard
-"@babel/plugin-transform-exponentiation-operator@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.23.3"
+"@babel/plugin-transform-exponentiation-operator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.25.9"
dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 5c33ee6a1bdc52fcdf0807f445b27e3fbdce33008531885e65a699762327565fffbcfde8395be7f21bcb22d582e425eddae45650c986462bb84ba68f43687516
+ checksum: 3b42f65bab3fee28c385115ce6bcb6ba544dff187012df408a432c9fb44c980afd898911020c723dc1c9257aaf3d7d0131ad83ba15102bf30ad9a86fc2a8a912
languageName: node
linkType: hard
-"@babel/plugin-transform-export-namespace-from@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-export-namespace-from@npm:7.23.4"
+"@babel/plugin-transform-export-namespace-from@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 38bf04f851e36240bbe83ace4169da626524f4107bfb91f05b4ad93a5fb6a36d5b3d30b8883c1ba575ccfc1bac7938e90ca2e3cb227f7b3f4a9424beec6fd4a7
+ checksum: f291ea2ec5f36de9028a00cbd5b32f08af281b8183bf047200ff001f4cb260be56f156b2449f42149448a4a033bd6e86a3a7f06d0c2825532eb0ae6b03058dfb
languageName: node
linkType: hard
-"@babel/plugin-transform-for-of@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-for-of@npm:7.23.3"
+"@babel/plugin-transform-for-of@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-for-of@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 8a36202cfee312ba80e509c7c2131e6773524e572b4dc64a8ee95bd912634fdeb5ea91c6c7747ee30e03562d0f0d333f88ed7dbb929b36b60b8d74189189e12f
+ checksum: bf11abc71934a1f369f39cd7a33cf3d4dc5673026a53f70b7c1238c4fcc44e68b3ca1bdbe3db2076f60defb6ffe117cbe10b90f3e1a613b551d88f7c4e693bbe
languageName: node
linkType: hard
-"@babel/plugin-transform-function-name@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-function-name@npm:7.23.3"
+"@babel/plugin-transform-function-name@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-function-name@npm:7.25.9"
dependencies:
- "@babel/helper-compilation-targets": "npm:^7.22.15"
- "@babel/helper-function-name": "npm:^7.23.0"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 89cb9747802118048115cf92a8f310752f02030549b26f008904990cbdc86c3d4a68e07ca3b5c46de8a46ed4df2cb576ac222c74c56de67253d2a3ddc2956083
+ checksum: 8e67fbd1dd367927b8b6afdf0a6e7cb3a3fd70766c52f700ca77428b6d536f6c9d7ec643e7762d64b23093233765c66bffa40e31aabe6492682879bcb45423e1
languageName: node
linkType: hard
-"@babel/plugin-transform-json-strings@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-json-strings@npm:7.23.4"
+"@babel/plugin-transform-json-strings@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-json-strings@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-json-strings": "npm:^7.8.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 39e82223992a9ad857722ae051291935403852ad24b0dd64c645ca1c10517b6bf9822377d88643fed8b3e61a4e3f7e5ae41cf90eb07c40a786505d47d5970e54
+ checksum: 00bc2d4751dfc9d44ab725be16ee534de13cfd7e77dfb386e5dac9e48101ce8fcbc5971df919dc25b3f8a0fa85d6dc5f2a0c3cf7ec9d61c163d9823c091844f0
languageName: node
linkType: hard
-"@babel/plugin-transform-literals@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-literals@npm:7.23.3"
+"@babel/plugin-transform-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-literals@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 8292106b106201464c2bfdd5c014fe6a9ca1c0256eb0a8031deb20081e21906fe68b156186f77d993c23eeab6d8d6f5f66e8895eec7ed97ce6de5dbcafbcd7f4
+ checksum: 00b14e9c14cf1e871c1f3781bf6334cac339c360404afd6aba63d2f6aca9270854d59a2b40abff1c4c90d4ffdca614440842d3043316c2f0ceb155fdf7726b3b
languageName: node
linkType: hard
-"@babel/plugin-transform-logical-assignment-operators@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.23.4"
+"@babel/plugin-transform-logical-assignment-operators@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 87b034dd13143904e405887e6125d76c27902563486efc66b7d9a9d8f9406b76c6ac42d7b37224014af5783d7edb465db0cdecd659fa3227baad0b3a6a35deff
+ checksum: 6e2051e10b2d6452980fc4bdef9da17c0d6ca48f81b8529e8804b031950e4fff7c74a7eb3de4a2b6ad22ffb631d0b67005425d232cce6e2b29ce861c78ed04f5
languageName: node
linkType: hard
-"@babel/plugin-transform-member-expression-literals@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-member-expression-literals@npm:7.23.3"
+"@babel/plugin-transform-member-expression-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 687f24f3ec60b627fef6e87b9e2770df77f76727b9d5f54fa4c84a495bb24eb4a20f1a6240fa22d339d45aac5eaeb1b39882e941bfd00cf498f9c53478d1ec88
+ checksum: 91d17b451bcc5ea9f1c6f8264144057ade3338d4b92c0b248366e4db3a7790a28fd59cc56ac433a9627a9087a17a5684e53f4995dd6ae92831cb72f1bd540b54
languageName: node
linkType: hard
-"@babel/plugin-transform-modules-amd@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-modules-amd@npm:7.23.3"
+"@babel/plugin-transform-modules-amd@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-amd@npm:7.25.9"
dependencies:
- "@babel/helper-module-transforms": "npm:^7.23.3"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 9f7ec036f7cfc588833a4dd117a44813b64aa4c1fd5bfb6c78f60198c1d290938213090c93a46f97a68a2490fad909e21a82b2472e95da74d108c125df21c8d5
+ checksum: 849957d9484d0a2d93331226ed6cf840cee7d57454549534c447c93f8b839ef8553eae9877f8f550e3c39f14d60992f91244b2e8e7502a46064b56c5d68ba855
languageName: node
linkType: hard
-"@babel/plugin-transform-modules-commonjs@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-modules-commonjs@npm:7.23.3"
+"@babel/plugin-transform-modules-commonjs@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-commonjs@npm:7.25.9"
dependencies:
- "@babel/helper-module-transforms": "npm:^7.23.3"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-simple-access": "npm:^7.22.5"
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-simple-access": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 5c8840c5c9ecba39367ae17c973ed13dbc43234147b77ae780eec65010e2a9993c5d717721b23e8179f7cf49decdd325c509b241d69cfbf92aa647a1d8d5a37d
+ checksum: 6ce771fb04d4810257fc8900374fece877dacaed74b05eaa16ad9224b390f43795c4d046cbe9ae304e1eb5aad035d37383895e3c64496d647c2128d183916e74
languageName: node
linkType: hard
-"@babel/plugin-transform-modules-systemjs@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-modules-systemjs@npm:7.23.3"
+"@babel/plugin-transform-modules-systemjs@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.9"
dependencies:
- "@babel/helper-hoist-variables": "npm:^7.22.5"
- "@babel/helper-module-transforms": "npm:^7.23.3"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-validator-identifier": "npm:^7.22.20"
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 0d55280a276510222c8896bf4e581acb84824aa5b14c824f7102242ad6bc5104aaffe5ab22fe4d27518f4ae2811bd59c36d0c0bfa695157f9cfce33f0517a069
+ checksum: 8299e3437542129c2684b86f98408c690df27db4122a79edded4782cf04e755d6ecb05b1e812c81a34224a81e664303392d5f3c36f3d2d51fdc99bb91c881e9a
languageName: node
linkType: hard
-"@babel/plugin-transform-modules-umd@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-modules-umd@npm:7.23.3"
+"@babel/plugin-transform-modules-umd@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-umd@npm:7.25.9"
dependencies:
- "@babel/helper-module-transforms": "npm:^7.23.3"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: f0d2f890a15b4367d0d8f160bed7062bdb145c728c24e9bfbc1211c7925aae5df72a88df3832c92dd2011927edfed4da1b1249e4c78402e893509316c0c2caa6
+ checksum: fa11a621f023e2ac437b71d5582f819e667c94306f022583d77da9a8f772c4128861a32bbb63bef5cba581a70cd7dbe87a37238edaafcfacf889470c395e7076
languageName: node
linkType: hard
-"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5"
+"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.9"
dependencies:
- "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: b0b072bef303670b5a98307bc37d1ac326cb7ad40ea162b89a03c2ffc465451be7ef05be95cb81ed28bfeb29670dc98fe911f793a67bceab18b4cb4c81ef48f3
+ checksum: 32b14fda5c885d1706863f8af2ee6c703d39264355b57482d3a24fce7f6afbd4c7a0896e501c0806ed2b0759beb621bf7f3f7de1fbbc82026039a98d961e78ef
languageName: node
linkType: hard
-"@babel/plugin-transform-new-target@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-new-target@npm:7.23.3"
+"@babel/plugin-transform-new-target@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-new-target@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: f489b9e1f17b42b2ba6312d58351e757cb23a8409f64f2bb6af4c09d015359588a5d68943b20756f141d0931a94431c782f3ed1225228a930a04b07be0c31b04
+ checksum: 7b5f1b7998f1cf183a7fa646346e2f3742e5805b609f28ad5fee22d666a15010f3e398b7e1ab78cddb7901841a3d3f47135929af23d54e8bf4ce69b72051f71e
languageName: node
linkType: hard
-"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.23.4"
+"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: bce490d22da5c87ff27fffaff6ad5a4d4979b8d7b72e30857f191e9c1e1824ba73bb8d7081166289369e388f94f0ce5383a593b1fc84d09464a062c75f824b0b
+ checksum: eb623db5be078a1c974afe7c7797b0309ba2ea9e9237c0b6831ade0f56d8248bb4ab3432ab34495ff8c877ec2fe412ff779d1e9b3c2b8139da18e1753d950bc3
languageName: node
linkType: hard
-"@babel/plugin-transform-numeric-separator@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-numeric-separator@npm:7.23.4"
+"@babel/plugin-transform-numeric-separator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: e34902da4f5588dc4812c92cb1f6a5e3e3647baf7b4623e30942f551bf1297621abec4e322ebfa50b320c987c0f34d9eb4355b3d289961d9035e2126e3119c12
+ checksum: ad63ad341977844b6f9535fcca15ca0d6d6ad112ed9cc509d4f6b75e9bf4b1b1a96a0bcb1986421a601505d34025373608b5f76d420d924b4e21f86b1a1f2749
languageName: node
linkType: hard
-"@babel/plugin-transform-object-rest-spread@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-object-rest-spread@npm:7.23.4"
+"@babel/plugin-transform-object-rest-spread@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.9"
dependencies:
- "@babel/compat-data": "npm:^7.23.3"
- "@babel/helper-compilation-targets": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3"
- "@babel/plugin-transform-parameters": "npm:^7.23.3"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/plugin-transform-parameters": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: b56017992ffe7fcd1dd9a9da67c39995a141820316266bcf7d77dc912980d228ccbd3f36191d234f5cc389b09157b5d2a955e33e8fb368319534affd1c72b262
+ checksum: 02077d8abd83bf6a48ff0b59e98d7561407cf75b591cffd3fdc5dc5e9a13dec1c847a7a690983762a3afecddb244831e897e0515c293e7c653b262c30cd614af
languageName: node
linkType: hard
-"@babel/plugin-transform-object-super@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-object-super@npm:7.23.3"
+"@babel/plugin-transform-object-super@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-object-super@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-replace-supers": "npm:^7.22.20"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-replace-supers": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: a6856fd8c0afbe5b3318c344d4d201d009f4051e2f6ff6237ff2660593e93c5997a58772b13d639077c3e29ced3440247b29c496cd77b13af1e7559a70009775
+ checksum: 0348d00e76f1f15ada44481a76e8c923d24cba91f6e49ee9b30d6861eb75344e7f84d62a18df8a6f9e9a7eacf992f388174b7f9cc4ce48287bcefca268c07600
languageName: node
linkType: hard
-"@babel/plugin-transform-optional-catch-binding@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.23.4"
+"@babel/plugin-transform-optional-catch-binding@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 4ef61812af0e4928485e28301226ce61139a8b8cea9e9a919215ebec4891b9fea2eb7a83dc3090e2679b7d7b2c8653da601fbc297d2addc54a908b315173991e
+ checksum: 722fd5ee12ab905309d4e84421584fce4b6d9e6b639b06afb20b23fa809e6ab251e908a8d5e8b14d066a28186b8ef8f58d69fd6eca9ce1b9ef7af08333378f6c
languageName: node
linkType: hard
-"@babel/plugin-transform-optional-chaining@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-optional-chaining@npm:7.23.4"
+"@babel/plugin-transform-optional-chaining@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5"
- "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 305b773c29ad61255b0e83ec1e92b2f7af6aa58be4cba1e3852bddaa14f7d2afd7b4438f41c28b179d6faac7eb8d4fb5530a17920294f25d459b8f84406bfbfb
+ checksum: 041ad2beae5affb8e68a0bcb6882a2dadb758db3c629a0e012f57488ab43a822ac1ea17a29db8ef36560a28262a5dfa4dbbbf06ed6e431db55abe024b7cd3961
languageName: node
linkType: hard
-"@babel/plugin-transform-parameters@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-parameters@npm:7.23.3"
+"@babel/plugin-transform-parameters@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-parameters@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: a8d4cbe0f6ba68d158f5b4215c63004fc37a1fdc539036eb388a9792017c8496ea970a1932ccb929308f61e53dc56676ed01d8df6f42bc0a85c7fd5ba82482b7
+ checksum: aecb446754b9e09d6b6fa95fd09e7cf682f8aaeed1d972874ba24c0a30a7e803ad5f014bb1fffc7bfeed22f93c0d200947407894ea59bf7687816f2f464f8df3
languageName: node
linkType: hard
-"@babel/plugin-transform-private-methods@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-private-methods@npm:7.23.3"
+"@babel/plugin-transform-private-methods@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-private-methods@npm:7.25.9"
dependencies:
- "@babel/helper-create-class-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 745a655edcd111b7f91882b921671ca0613079760d8c9befe336b8a9bc4ce6bb49c0c08941831c950afb1b225b4b2d3eaac8842e732db095b04db38efd8c34f4
+ checksum: 64bd71de93d39daefa3e6c878d6f2fd238ed7d4ecfb13b0e771ddbbc131487def3ceb405b62b534a5cbb5043046b504e1b189b0a45229cc75af979a9fbcaa7bd
languageName: node
linkType: hard
-"@babel/plugin-transform-private-property-in-object@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-private-property-in-object@npm:7.23.4"
+"@babel/plugin-transform-private-property-in-object@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-create-class-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 8d31b28f24204b4d13514cd3a8f3033abf575b1a6039759ddd6e1d82dd33ba7281f9bc85c9f38072a665d69bfa26dc40737eefaf9d397b024654a483d2357bf5
+ checksum: d4965de19d9f204e692cc74dbc39f0bb469e5f29df96dd4457ea23c5e5596fba9d5af76eaa96f9d48a9fc20ec5f12a94c679285e36b8373406868ea228109e27
languageName: node
linkType: hard
-"@babel/plugin-transform-property-literals@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-property-literals@npm:7.23.3"
+"@babel/plugin-transform-property-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-property-literals@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: b2549f23f90cf276c2e3058c2225c3711c2ad1c417e336d3391199445a9776dd791b83be47b2b9a7ae374b40652d74b822387e31fa5267a37bf49c122e1a9747
+ checksum: 1639e35b2438ccf3107af760d34e6a8e4f9acdd3ae6186ae771a6e3029bd59dfe778e502d67090f1185ecda5c16addfed77561e39c518a3f51ff10d41790e106
languageName: node
linkType: hard
-"@babel/plugin-transform-react-constant-elements@npm:^7.18.12":
- version: 7.23.3
- resolution: "@babel/plugin-transform-react-constant-elements@npm:7.23.3"
+"@babel/plugin-transform-react-constant-elements@npm:^7.21.3":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-constant-elements@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: c009668e5212841ee11510b887963b6d10abd9a53c67f3f4eb7e191d51bc7fca8abfe9d27e9ee977cc8675aa0c9a3d4cdc4b7fac91059c165ec9eb49c18dadde
+ checksum: 50aca3df122cf801abd251cc2507ef3011ead8f047d31d8f35b10627dd722f6a165245b09e81b3c6876515fd266a97aed0052f6b409aa1fe961fb36dd7cc0822
languageName: node
linkType: hard
-"@babel/plugin-transform-react-display-name@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-react-display-name@npm:7.23.3"
+"@babel/plugin-transform-react-display-name@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-display-name@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 3aed142af7bd1aed1df2bdad91ed33ba1cdd5c3c67ce6eafba821ff72f129162a197ffb55f1eb1775af276abd5545934489a8257fef6c6665ddf253a4f39a939
+ checksum: 63a0f962d64e71baf87c212755419e25c637d2d95ea6fdc067df26b91e606ae186442ae815b99a577eca9bf5404d9577ecad218a3cf42d0e9e286ca7b003a992
languageName: node
linkType: hard
-"@babel/plugin-transform-react-jsx-development@npm:^7.22.5":
- version: 7.22.5
- resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5"
+"@babel/plugin-transform-react-jsx-development@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.9"
dependencies:
- "@babel/plugin-transform-react-jsx": "npm:^7.22.5"
+ "@babel/plugin-transform-react-jsx": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 4d2e9e68383238feb873f6111df972df4a2ebf6256d6f787a8772241867efa975b3980f7d75ab7d750e7eaad4bd454e8cc6e106301fd7572dd389e553f5f69d2
+ checksum: c0b92ff9eb029620abf320ff74aae182cea87524723d740fb48a4373d0d16bddf5edbe1116e7ba341332a5337e55c2ceaee8b8cad5549e78af7f4b3cfe77debb
languageName: node
linkType: hard
-"@babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.22.5":
- version: 7.23.4
- resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4"
+"@babel/plugin-transform-react-jsx@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-jsx@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-module-imports": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-jsx": "npm:^7.23.3"
- "@babel/types": "npm:^7.23.4"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/plugin-syntax-jsx": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 8851b3adc515cd91bdb06ff3a23a0f81f0069cfef79dfb3fa744da4b7a82e3555ccb6324c4fa71ecf22508db13b9ff6a0ed96675f95fc87903b9fc6afb699580
+ checksum: 5c9947e8ed141f7606f54da3e05eea1074950c5b8354c39df69cb7f43cb5a83c6c9d7973b24bc3d89341c8611f8ad50830a98ab10d117d850e6bdd8febdce221
languageName: node
linkType: hard
-"@babel/plugin-transform-react-pure-annotations@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.23.3"
+"@babel/plugin-transform-react-pure-annotations@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 76287adeab656fb7f39243e5ab6a8c60069cf69fffeebd1566457d56cb2f966366a23bd755d3e369f4d0437459e3b76243df370caa7d7d2287a8560b66c53ca2
+ checksum: 7c8eac04644ad19dcd71bb8e949b0ae22b9e548fa4a58e545d3d0342f647fb89db7f8789a7c5b8074d478ce6d3d581eaf47dd4b36027e16fd68211c383839abc
languageName: node
linkType: hard
-"@babel/plugin-transform-regenerator@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-regenerator@npm:7.23.3"
+"@babel/plugin-transform-regenerator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-regenerator@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
regenerator-transform: "npm:^0.15.2"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 3b0e989ae5db78894ee300b24e07fbcec490c39ab48629c519377581cf94e90308f4ddc10a8914edc9f403e2d3ac7a7ae0ae09003629d852da03e2ba846299c6
+ checksum: eef3ffc19f7d291b863635f32b896ad7f87806d9219a0d3404a470219abcfc5b43aabecd691026c48e875b965760d9c16abee25e6447272233f30cd07f453ec7
languageName: node
linkType: hard
-"@babel/plugin-transform-reserved-words@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-reserved-words@npm:7.23.3"
+"@babel/plugin-transform-regexp-modifiers@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.26.0"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 4abc1db6c964efafc7a927cda814c7275275afa4b530483e0936fd614de23cb5802f7ca43edaa402008a723d4e7eac282b6f5283aa2eeb3b27da6d6c1dd7f8ed
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-reserved-words@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-reserved-words@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 4e6d61f6c9757592661cfbd2c39c4f61551557b98cb5f0995ef10f5540f67e18dde8a42b09716d58943b6e4b7ef5c9bcf19902839e7328a4d49149e0fecdbfcd
+ checksum: 8b028b80d1983e3e02f74e21924323cc66ba930e5c5758909a122aa7d80e341b8b0f42e1698e42b50d47a6ba911332f584200b28e1a4e2104b7514d9dc011e96
languageName: node
linkType: hard
-"@babel/plugin-transform-runtime@npm:^7.22.9":
- version: 7.23.4
- resolution: "@babel/plugin-transform-runtime@npm:7.23.4"
+"@babel/plugin-transform-runtime@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-runtime@npm:7.25.9"
dependencies:
- "@babel/helper-module-imports": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- babel-plugin-polyfill-corejs2: "npm:^0.4.6"
- babel-plugin-polyfill-corejs3: "npm:^0.8.5"
- babel-plugin-polyfill-regenerator: "npm:^0.5.3"
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ babel-plugin-polyfill-corejs2: "npm:^0.4.10"
+ babel-plugin-polyfill-corejs3: "npm:^0.10.6"
+ babel-plugin-polyfill-regenerator: "npm:^0.6.1"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 6ac29012550cdd10b65ec43fef0c7f43904ec458c43d597f627d8f52807413e57ea94e3986dbace576d734e67c2d09be5e43e77c72567d18f8c4ac5e19844625
+ checksum: 888a4998ba0a2313de347954c9a8dfeccbff0633c69d33aee385b8878eba2b429dbfb00c3cc04f6bca454b9be8afa01ebbd73defb7fbbb6e2d3086205c07758b
languageName: node
linkType: hard
-"@babel/plugin-transform-shorthand-properties@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-shorthand-properties@npm:7.23.3"
+"@babel/plugin-transform-shorthand-properties@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: c423c66fec0b6503f50561741754c84366ef9e9818442c8881fbaa90cc363fd137084b9431cdc00ed2f1fd8c8a1a5982c4a7e1f2af3769db4caf2ac7ea55d4f0
+ checksum: 05a20d45f0fb62567644c507ccd4e379c1a74dacf887d2b2cac70247415e3f6d7d3bf4850c8b336053144715fedb6200fc38f7130c4b76c94eec9b9c0c2a8e9b
languageName: node
linkType: hard
-"@babel/plugin-transform-spread@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-spread@npm:7.23.3"
+"@babel/plugin-transform-spread@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-spread@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: a348e4ae47e4ceeceb760506ec7bf835ccc18a2cf70ec74ebfbe41bc172fa2412b05b7d1b86836f8aee375e41a04ff20486074778d0e2d19d668b33dc52e9dbb
+ checksum: 996c8fed238efc30e0664f9f58bd7ec8c148f4659f84425f68923a094fe891245711d26eb10d1f815f50c124434e076e860dbe9662240844d1b77cd09907dcdf
languageName: node
linkType: hard
-"@babel/plugin-transform-sticky-regex@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-sticky-regex@npm:7.23.3"
+"@babel/plugin-transform-sticky-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: cd15c407906b41e4b924ea151e455c11274dba050771ee7154ad88a1a274140ac5e84efc8d08c4379f2f0cec8a09e4a0a3b2a3a954ba6a67d9fb35df1c714c56
+ checksum: e9612b0615dab4c4fba1c560769616a9bd7b9226c73191ef84b6c3ee185c8b719b4f887cdd8336a0a13400ce606ab4a0d33bc8fa6b4fcdb53e2896d07f2568f6
languageName: node
linkType: hard
-"@babel/plugin-transform-template-literals@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-template-literals@npm:7.23.3"
+"@babel/plugin-transform-template-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-template-literals@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 9b5f43788b9ffcb8f2b445a16b1aa40fcf23cb0446a4649445f098ec6b4cb751f243a535da623d59fefe48f4c40552f5621187a61811779076bab26863e3373d
+ checksum: 5144da6036807bbd4e9d2a8b92ae67a759543929f34f4db9b463448a77298f4a40bf1e92e582db208fe08ee116224806a3bd0bed75d9da404fc2c0af9e6da540
languageName: node
linkType: hard
-"@babel/plugin-transform-typeof-symbol@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-typeof-symbol@npm:7.23.3"
+"@babel/plugin-transform-typeof-symbol@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-typeof-symbol@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 50e81d84c6059878be2a0e41e0d790cab10882cfb8fa85e8c2665ccb0b3cd7233f49197f17427bc7c1b36c80e07076640ecf1b641888d78b9cb91bc16478d84a
+ checksum: 2b19fd88608589d9bc6b607ff17b06791d35c67ef3249f4659283454e6a9984241e3bd4c4eb72bb8b3d860a73223f3874558b861adb7314aa317c1c6a2f0cafb
languageName: node
linkType: hard
-"@babel/plugin-transform-typescript@npm:^7.23.3":
- version: 7.23.4
- resolution: "@babel/plugin-transform-typescript@npm:7.23.4"
+"@babel/plugin-transform-typescript@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-typescript@npm:7.25.9"
dependencies:
- "@babel/helper-annotate-as-pure": "npm:^7.22.5"
- "@babel/helper-create-class-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/plugin-syntax-typescript": "npm:^7.23.3"
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ "@babel/plugin-syntax-typescript": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 657294f8e0d59fc2b765a230cd1635a575c2dee33aba45e8fc0fbe6ef86ffae007f8c9ca41665ac9629f49a922caf844d14b9a7990dddd2f64aee969d6fb14a4
+ checksum: c607ddb45f7e33cfcb928aad05cb1b18b1ecb564d2329d8f8e427f75192511aa821dee42d26871f1bdffbd883853e150ba81436664646c6e6b13063e65ce1475
languageName: node
linkType: hard
-"@babel/plugin-transform-unicode-escapes@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-unicode-escapes@npm:7.23.3"
+"@babel/plugin-transform-unicode-escapes@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: f1ed54742dc982666f471df5d087cfda9c6dbf7842bec2d0f7893ed359b142a38c0210358f297ab5c7a3e11ec0dfb0e523de2e2edf48b62f257aaadd5f068866
+ checksum: 615c84d7c53e1575d54ba9257e753e0b98c5de1e3225237d92f55226eaab8eb5bceb74df43f50f4aa162b0bbcc934ed11feafe2b60b8ec4934ce340fad4b8828
languageName: node
linkType: hard
-"@babel/plugin-transform-unicode-property-regex@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.23.3"
+"@babel/plugin-transform-unicode-property-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.9"
dependencies:
- "@babel/helper-create-regexp-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: dca5702d43fac70351623a12e4dfa454fd028a67498888522b644fd1a02534fabd440106897e886ebcc6ce6a39c58094ca29953b6f51bc67372aa8845a5ae49f
+ checksum: 1685836fc38af4344c3d2a9edbd46f7c7b28d369b63967d5b83f2f6849ec45b97223461cea3d14cc3f0be6ebb284938e637a5ca3955c0e79c873d62f593d615c
languageName: node
linkType: hard
-"@babel/plugin-transform-unicode-regex@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-unicode-regex@npm:7.23.3"
+"@babel/plugin-transform-unicode-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.9"
dependencies:
- "@babel/helper-create-regexp-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: df824dcca2f6e731f61d69103e87d5dd974d8a04e46e28684a4ba935ae633d876bded09b8db890fd72d0caf7b9638e2672b753671783613cc78d472951e2df8c
+ checksum: 448004f978279e726af26acd54f63f9002c9e2582ecd70d1c5c4436f6de490fcd817afb60016d11c52f5ef17dbaac2590e8cc7bfaf4e91b58c452cf188c7920f
languageName: node
linkType: hard
-"@babel/plugin-transform-unicode-sets-regex@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.23.3"
+"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.9"
dependencies:
- "@babel/helper-create-regexp-features-plugin": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 30fe1d29af8395a867d40a63a250ca89072033d9bc7d4587eeebeaf4ad7f776aab83064321bfdb1d09d7e29a1d392852361f4f60a353f0f4d1a3b435dcbf256b
+ checksum: 56ee04fbe236b77cbcd6035cbf0be7566d1386b8349154ac33244c25f61170c47153a9423cd1d92855f7d6447b53a4a653d9e8fd1eaeeee14feb4b2baf59bd9f
languageName: node
linkType: hard
-"@babel/preset-env@npm:^7.19.4, @babel/preset-env@npm:^7.22.9":
- version: 7.23.3
- resolution: "@babel/preset-env@npm:7.23.3"
+"@babel/preset-env@npm:^7.20.2, @babel/preset-env@npm:^7.25.9":
+ version: 7.26.0
+ resolution: "@babel/preset-env@npm:7.26.0"
dependencies:
- "@babel/compat-data": "npm:^7.23.3"
- "@babel/helper-compilation-targets": "npm:^7.22.15"
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-validator-option": "npm:^7.22.15"
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.23.3"
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.23.3"
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.23.3"
+ "@babel/compat-data": "npm:^7.26.0"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.9"
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.9"
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.9"
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.9"
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.9"
"@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2"
- "@babel/plugin-syntax-async-generators": "npm:^7.8.4"
- "@babel/plugin-syntax-class-properties": "npm:^7.12.13"
- "@babel/plugin-syntax-class-static-block": "npm:^7.14.5"
- "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3"
- "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3"
- "@babel/plugin-syntax-import-assertions": "npm:^7.23.3"
- "@babel/plugin-syntax-import-attributes": "npm:^7.23.3"
- "@babel/plugin-syntax-import-meta": "npm:^7.10.4"
- "@babel/plugin-syntax-json-strings": "npm:^7.8.3"
- "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4"
- "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3"
- "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4"
- "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3"
- "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3"
- "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3"
- "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5"
- "@babel/plugin-syntax-top-level-await": "npm:^7.14.5"
+ "@babel/plugin-syntax-import-assertions": "npm:^7.26.0"
+ "@babel/plugin-syntax-import-attributes": "npm:^7.26.0"
"@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6"
- "@babel/plugin-transform-arrow-functions": "npm:^7.23.3"
- "@babel/plugin-transform-async-generator-functions": "npm:^7.23.3"
- "@babel/plugin-transform-async-to-generator": "npm:^7.23.3"
- "@babel/plugin-transform-block-scoped-functions": "npm:^7.23.3"
- "@babel/plugin-transform-block-scoping": "npm:^7.23.3"
- "@babel/plugin-transform-class-properties": "npm:^7.23.3"
- "@babel/plugin-transform-class-static-block": "npm:^7.23.3"
- "@babel/plugin-transform-classes": "npm:^7.23.3"
- "@babel/plugin-transform-computed-properties": "npm:^7.23.3"
- "@babel/plugin-transform-destructuring": "npm:^7.23.3"
- "@babel/plugin-transform-dotall-regex": "npm:^7.23.3"
- "@babel/plugin-transform-duplicate-keys": "npm:^7.23.3"
- "@babel/plugin-transform-dynamic-import": "npm:^7.23.3"
- "@babel/plugin-transform-exponentiation-operator": "npm:^7.23.3"
- "@babel/plugin-transform-export-namespace-from": "npm:^7.23.3"
- "@babel/plugin-transform-for-of": "npm:^7.23.3"
- "@babel/plugin-transform-function-name": "npm:^7.23.3"
- "@babel/plugin-transform-json-strings": "npm:^7.23.3"
- "@babel/plugin-transform-literals": "npm:^7.23.3"
- "@babel/plugin-transform-logical-assignment-operators": "npm:^7.23.3"
- "@babel/plugin-transform-member-expression-literals": "npm:^7.23.3"
- "@babel/plugin-transform-modules-amd": "npm:^7.23.3"
- "@babel/plugin-transform-modules-commonjs": "npm:^7.23.3"
- "@babel/plugin-transform-modules-systemjs": "npm:^7.23.3"
- "@babel/plugin-transform-modules-umd": "npm:^7.23.3"
- "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.22.5"
- "@babel/plugin-transform-new-target": "npm:^7.23.3"
- "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.23.3"
- "@babel/plugin-transform-numeric-separator": "npm:^7.23.3"
- "@babel/plugin-transform-object-rest-spread": "npm:^7.23.3"
- "@babel/plugin-transform-object-super": "npm:^7.23.3"
- "@babel/plugin-transform-optional-catch-binding": "npm:^7.23.3"
- "@babel/plugin-transform-optional-chaining": "npm:^7.23.3"
- "@babel/plugin-transform-parameters": "npm:^7.23.3"
- "@babel/plugin-transform-private-methods": "npm:^7.23.3"
- "@babel/plugin-transform-private-property-in-object": "npm:^7.23.3"
- "@babel/plugin-transform-property-literals": "npm:^7.23.3"
- "@babel/plugin-transform-regenerator": "npm:^7.23.3"
- "@babel/plugin-transform-reserved-words": "npm:^7.23.3"
- "@babel/plugin-transform-shorthand-properties": "npm:^7.23.3"
- "@babel/plugin-transform-spread": "npm:^7.23.3"
- "@babel/plugin-transform-sticky-regex": "npm:^7.23.3"
- "@babel/plugin-transform-template-literals": "npm:^7.23.3"
- "@babel/plugin-transform-typeof-symbol": "npm:^7.23.3"
- "@babel/plugin-transform-unicode-escapes": "npm:^7.23.3"
- "@babel/plugin-transform-unicode-property-regex": "npm:^7.23.3"
- "@babel/plugin-transform-unicode-regex": "npm:^7.23.3"
- "@babel/plugin-transform-unicode-sets-regex": "npm:^7.23.3"
+ "@babel/plugin-transform-arrow-functions": "npm:^7.25.9"
+ "@babel/plugin-transform-async-generator-functions": "npm:^7.25.9"
+ "@babel/plugin-transform-async-to-generator": "npm:^7.25.9"
+ "@babel/plugin-transform-block-scoped-functions": "npm:^7.25.9"
+ "@babel/plugin-transform-block-scoping": "npm:^7.25.9"
+ "@babel/plugin-transform-class-properties": "npm:^7.25.9"
+ "@babel/plugin-transform-class-static-block": "npm:^7.26.0"
+ "@babel/plugin-transform-classes": "npm:^7.25.9"
+ "@babel/plugin-transform-computed-properties": "npm:^7.25.9"
+ "@babel/plugin-transform-destructuring": "npm:^7.25.9"
+ "@babel/plugin-transform-dotall-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-duplicate-keys": "npm:^7.25.9"
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-dynamic-import": "npm:^7.25.9"
+ "@babel/plugin-transform-exponentiation-operator": "npm:^7.25.9"
+ "@babel/plugin-transform-export-namespace-from": "npm:^7.25.9"
+ "@babel/plugin-transform-for-of": "npm:^7.25.9"
+ "@babel/plugin-transform-function-name": "npm:^7.25.9"
+ "@babel/plugin-transform-json-strings": "npm:^7.25.9"
+ "@babel/plugin-transform-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-logical-assignment-operators": "npm:^7.25.9"
+ "@babel/plugin-transform-member-expression-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-amd": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-commonjs": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-systemjs": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-umd": "npm:^7.25.9"
+ "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-new-target": "npm:^7.25.9"
+ "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.25.9"
+ "@babel/plugin-transform-numeric-separator": "npm:^7.25.9"
+ "@babel/plugin-transform-object-rest-spread": "npm:^7.25.9"
+ "@babel/plugin-transform-object-super": "npm:^7.25.9"
+ "@babel/plugin-transform-optional-catch-binding": "npm:^7.25.9"
+ "@babel/plugin-transform-optional-chaining": "npm:^7.25.9"
+ "@babel/plugin-transform-parameters": "npm:^7.25.9"
+ "@babel/plugin-transform-private-methods": "npm:^7.25.9"
+ "@babel/plugin-transform-private-property-in-object": "npm:^7.25.9"
+ "@babel/plugin-transform-property-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-regenerator": "npm:^7.25.9"
+ "@babel/plugin-transform-regexp-modifiers": "npm:^7.26.0"
+ "@babel/plugin-transform-reserved-words": "npm:^7.25.9"
+ "@babel/plugin-transform-shorthand-properties": "npm:^7.25.9"
+ "@babel/plugin-transform-spread": "npm:^7.25.9"
+ "@babel/plugin-transform-sticky-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-template-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-typeof-symbol": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-escapes": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-property-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.9"
"@babel/preset-modules": "npm:0.1.6-no-external-plugins"
- babel-plugin-polyfill-corejs2: "npm:^0.4.6"
- babel-plugin-polyfill-corejs3: "npm:^0.8.5"
- babel-plugin-polyfill-regenerator: "npm:^0.5.3"
- core-js-compat: "npm:^3.31.0"
+ babel-plugin-polyfill-corejs2: "npm:^0.4.10"
+ babel-plugin-polyfill-corejs3: "npm:^0.10.6"
+ babel-plugin-polyfill-regenerator: "npm:^0.6.1"
+ core-js-compat: "npm:^3.38.1"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 36b02a86817ab5474bb74a8d62a110723b0b05904a52ddc5627cf89457525b8d5ac0739b8e435a6ae12ef8b90cd5fc191169898c3dc2ac9d2c84026b02f2580a
+ checksum: 26e19dc407cfa1c5166be638b4c54239d084fe15d8d7e6306d8c6dc7bc1decc51070a8dcf28352c1a2feeefbe52a06d193a12e302327ad5f529583df75fb7a26
languageName: node
linkType: hard
@@ -1557,55 +1425,48 @@ __metadata:
languageName: node
linkType: hard
-"@babel/preset-react@npm:^7.18.6, @babel/preset-react@npm:^7.22.5":
- version: 7.23.3
- resolution: "@babel/preset-react@npm:7.23.3"
+"@babel/preset-react@npm:^7.18.6, @babel/preset-react@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/preset-react@npm:7.25.9"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-validator-option": "npm:^7.22.15"
- "@babel/plugin-transform-react-display-name": "npm:^7.23.3"
- "@babel/plugin-transform-react-jsx": "npm:^7.22.15"
- "@babel/plugin-transform-react-jsx-development": "npm:^7.22.5"
- "@babel/plugin-transform-react-pure-annotations": "npm:^7.23.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-transform-react-display-name": "npm:^7.25.9"
+ "@babel/plugin-transform-react-jsx": "npm:^7.25.9"
+ "@babel/plugin-transform-react-jsx-development": "npm:^7.25.9"
+ "@babel/plugin-transform-react-pure-annotations": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: cecb2493e09fd4ffa5effcef1d06e968386b1bfe077a99834f7e8ef249208274fca62fe5a6b3986ef1c1c3900b2eb409adb528ae1b73dba31397b16f9262e83c
+ checksum: c294b475ee741f01f63ea0d828862811c453fabc6023f01814ce983bc316388e9d73290164d2b1384c2684db9c330803a3d4d2170285b105dcbacd483329eb93
languageName: node
linkType: hard
-"@babel/preset-typescript@npm:^7.18.6, @babel/preset-typescript@npm:^7.22.5":
- version: 7.23.3
- resolution: "@babel/preset-typescript@npm:7.23.3"
+"@babel/preset-typescript@npm:^7.21.0, @babel/preset-typescript@npm:^7.25.9":
+ version: 7.26.0
+ resolution: "@babel/preset-typescript@npm:7.26.0"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-validator-option": "npm:^7.22.15"
- "@babel/plugin-syntax-jsx": "npm:^7.23.3"
- "@babel/plugin-transform-modules-commonjs": "npm:^7.23.3"
- "@babel/plugin-transform-typescript": "npm:^7.23.3"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-syntax-jsx": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-commonjs": "npm:^7.25.9"
+ "@babel/plugin-transform-typescript": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: e72b654c7f0f08b35d7e1c0e3a59c0c13037f295c425760b8b148aa7dde01e6ddd982efc525710f997a1494fafdd55cb525738c016609e7e4d703d02014152b7
- languageName: node
- linkType: hard
-
-"@babel/regjsgen@npm:^0.8.0":
- version: 0.8.0
- resolution: "@babel/regjsgen@npm:0.8.0"
- checksum: 4f3ddd8c7c96d447e05c8304c1d5ba3a83fcabd8a716bc1091c2f31595cdd43a3a055fff7cb5d3042b8cb7d402d78820fcb4e05d896c605a7d8bcf30f2424c4a
+ checksum: 20d86bc45d2bbfde2f84fc7d7b38746fa6481d4bde6643039ad4b1ff0b804c6d210ee43e6830effd8571f2ff43fa7ffd27369f42f2b3a2518bb92dc86c780c61
languageName: node
linkType: hard
-"@babel/runtime-corejs3@npm:^7.22.6":
- version: 7.23.4
- resolution: "@babel/runtime-corejs3@npm:7.23.4"
+"@babel/runtime-corejs3@npm:^7.25.9":
+ version: 7.26.0
+ resolution: "@babel/runtime-corejs3@npm:7.26.0"
dependencies:
core-js-pure: "npm:^3.30.2"
regenerator-runtime: "npm:^0.14.0"
- checksum: 31fa117b451fb8f34290aa7bd2016f12254663e78641f75ec28599c5d6a63f4f7c0e796eced0bb89194a491dfae0edc61364d0ffb4efbf19a9e46bfca6848a58
+ checksum: 921fa27c004cf2b92f0d49efc2006cfc1a72d2a35c7374da8ec88d8b63543963e6ef29d4820e068a7892a7d553dc2bac7208aef8fef30642bc843b63255b650b
languageName: node
linkType: hard
-"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.8.4":
+"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.3, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.8.4":
version: 7.23.4
resolution: "@babel/runtime@npm:7.23.4"
dependencies:
@@ -1614,36 +1475,52 @@ __metadata:
languageName: node
linkType: hard
-"@babel/template@npm:^7.22.15":
- version: 7.22.15
- resolution: "@babel/template@npm:7.22.15"
+"@babel/runtime@npm:^7.25.9":
+ version: 7.26.0
+ resolution: "@babel/runtime@npm:7.26.0"
dependencies:
- "@babel/code-frame": "npm:^7.22.13"
- "@babel/parser": "npm:^7.22.15"
- "@babel/types": "npm:^7.22.15"
- checksum: 9312edd37cf1311d738907003f2aa321a88a42ba223c69209abe4d7111db019d321805504f606c7fd75f21c6cf9d24d0a8223104cd21ebd207e241b6c551f454
+ regenerator-runtime: "npm:^0.14.0"
+ checksum: 12c01357e0345f89f4f7e8c0e81921f2a3e3e101f06e8eaa18a382b517376520cd2fa8c237726eb094dab25532855df28a7baaf1c26342b52782f6936b07c287
languageName: node
linkType: hard
-"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.3, @babel/traverse@npm:^7.23.4":
- version: 7.23.4
- resolution: "@babel/traverse@npm:7.23.4"
- dependencies:
- "@babel/code-frame": "npm:^7.23.4"
- "@babel/generator": "npm:^7.23.4"
- "@babel/helper-environment-visitor": "npm:^7.22.20"
- "@babel/helper-function-name": "npm:^7.23.0"
- "@babel/helper-hoist-variables": "npm:^7.22.5"
- "@babel/helper-split-export-declaration": "npm:^7.22.6"
- "@babel/parser": "npm:^7.23.4"
- "@babel/types": "npm:^7.23.4"
- debug: "npm:^4.1.0"
+"@babel/template@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/template@npm:7.25.9"
+ dependencies:
+ "@babel/code-frame": "npm:^7.25.9"
+ "@babel/parser": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: ebe677273f96a36c92cc15b7aa7b11cc8bc8a3bb7a01d55b2125baca8f19cae94ff3ce15f1b1880fb8437f3a690d9f89d4e91f16fc1dc4d3eb66226d128983ab
+ languageName: node
+ linkType: hard
+
+"@babel/traverse@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/traverse@npm:7.25.9"
+ dependencies:
+ "@babel/code-frame": "npm:^7.25.9"
+ "@babel/generator": "npm:^7.25.9"
+ "@babel/parser": "npm:^7.25.9"
+ "@babel/template": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ debug: "npm:^4.3.1"
globals: "npm:^11.1.0"
- checksum: a423d2b90934efe4ed423d67d91d6aa33ad035d6a175420fa9715376720584b4e7a7002be4bf55b085b7e675b7aba8c615e01560d6d9c47341427e1fe8039c68
+ checksum: e90be586a714da4adb80e6cb6a3c5cfcaa9b28148abdafb065e34cc109676fc3db22cf98cd2b2fff66ffb9b50c0ef882cab0f466b6844be0f6c637b82719bba1
languageName: node
linkType: hard
-"@babel/types@npm:^7.20.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
+"@babel/types@npm:^7.21.3, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/types@npm:7.26.0"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ checksum: b694f41ad1597127e16024d766c33a641508aad037abd08d0d1f73af753e1119fa03b4a107d04b5f92cc19c095a594660547ae9bead1db2299212d644b0a5cb8
+ languageName: node
+ linkType: hard
+
+"@babel/types@npm:^7.4.4":
version: 7.23.4
resolution: "@babel/types@npm:7.23.4"
dependencies:
@@ -1701,120 +1578,170 @@ __metadata:
languageName: node
linkType: hard
-"@docusaurus/core@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/core@npm:3.0.0"
+"@docusaurus/babel@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/babel@npm:3.6.1"
dependencies:
- "@babel/core": "npm:^7.22.9"
- "@babel/generator": "npm:^7.22.9"
+ "@babel/core": "npm:^7.25.9"
+ "@babel/generator": "npm:^7.25.9"
"@babel/plugin-syntax-dynamic-import": "npm:^7.8.3"
- "@babel/plugin-transform-runtime": "npm:^7.22.9"
- "@babel/preset-env": "npm:^7.22.9"
- "@babel/preset-react": "npm:^7.22.5"
- "@babel/preset-typescript": "npm:^7.22.5"
- "@babel/runtime": "npm:^7.22.6"
- "@babel/runtime-corejs3": "npm:^7.22.6"
- "@babel/traverse": "npm:^7.22.8"
- "@docusaurus/cssnano-preset": "npm:3.0.0"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/mdx-loader": "npm:3.0.0"
- "@docusaurus/react-loadable": "npm:5.5.2"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-common": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
- "@slorber/static-site-generator-webpack-plugin": "npm:^4.0.7"
- "@svgr/webpack": "npm:^6.5.1"
- autoprefixer: "npm:^10.4.14"
- babel-loader: "npm:^9.1.3"
+ "@babel/plugin-transform-runtime": "npm:^7.25.9"
+ "@babel/preset-env": "npm:^7.25.9"
+ "@babel/preset-react": "npm:^7.25.9"
+ "@babel/preset-typescript": "npm:^7.25.9"
+ "@babel/runtime": "npm:^7.25.9"
+ "@babel/runtime-corejs3": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
babel-plugin-dynamic-import-node: "npm:^2.3.3"
+ fs-extra: "npm:^11.1.1"
+ tslib: "npm:^2.6.0"
+ checksum: 66e3ce0e837e6d507539c1cf9754ff5e7e0d0198c9d5cf0b99c5de48bccdf747b6bc3459f267c0123587a8497cbe2b7241bd49dfeb8a5a5e2b015088e4e2a908
+ languageName: node
+ linkType: hard
+
+"@docusaurus/bundler@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/bundler@npm:3.6.1"
+ dependencies:
+ "@babel/core": "npm:^7.25.9"
+ "@docusaurus/babel": "npm:3.6.1"
+ "@docusaurus/cssnano-preset": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ autoprefixer: "npm:^10.4.14"
+ babel-loader: "npm:^9.2.1"
+ clean-css: "npm:^5.3.2"
+ copy-webpack-plugin: "npm:^11.0.0"
+ css-loader: "npm:^6.8.1"
+ css-minimizer-webpack-plugin: "npm:^5.0.1"
+ cssnano: "npm:^6.1.2"
+ file-loader: "npm:^6.2.0"
+ html-minifier-terser: "npm:^7.2.0"
+ mini-css-extract-plugin: "npm:^2.9.1"
+ null-loader: "npm:^4.0.1"
+ postcss: "npm:^8.4.26"
+ postcss-loader: "npm:^7.3.3"
+ react-dev-utils: "npm:^12.0.1"
+ terser-webpack-plugin: "npm:^5.3.9"
+ tslib: "npm:^2.6.0"
+ url-loader: "npm:^4.1.1"
+ webpack: "npm:^5.95.0"
+ webpackbar: "npm:^6.0.1"
+ peerDependencies:
+ "@docusaurus/faster": "*"
+ peerDependenciesMeta:
+ "@docusaurus/faster":
+ optional: true
+ checksum: 03f7b04cb9bd9e0877eeadda1ccf5d097b952aebad4840f4ce170f477652e8a30d37c04a9d9c3dd857ece193e9ce35cccff144e7bf521f35fee2e6a053dd9bc2
+ languageName: node
+ linkType: hard
+
+"@docusaurus/core@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/core@npm:3.6.1"
+ dependencies:
+ "@docusaurus/babel": "npm:3.6.1"
+ "@docusaurus/bundler": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/mdx-loader": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
boxen: "npm:^6.2.1"
chalk: "npm:^4.1.2"
chokidar: "npm:^3.5.3"
- clean-css: "npm:^5.3.2"
cli-table3: "npm:^0.6.3"
combine-promises: "npm:^1.1.0"
commander: "npm:^5.1.0"
- copy-webpack-plugin: "npm:^11.0.0"
core-js: "npm:^3.31.1"
- css-loader: "npm:^6.8.1"
- css-minimizer-webpack-plugin: "npm:^4.2.2"
- cssnano: "npm:^5.1.15"
del: "npm:^6.1.1"
detect-port: "npm:^1.5.1"
escape-html: "npm:^1.0.3"
eta: "npm:^2.2.0"
- file-loader: "npm:^6.2.0"
+ eval: "npm:^0.1.8"
fs-extra: "npm:^11.1.1"
- html-minifier-terser: "npm:^7.2.0"
html-tags: "npm:^3.3.1"
- html-webpack-plugin: "npm:^5.5.3"
+ html-webpack-plugin: "npm:^5.6.0"
leven: "npm:^3.1.0"
lodash: "npm:^4.17.21"
- mini-css-extract-plugin: "npm:^2.7.6"
- postcss: "npm:^8.4.26"
- postcss-loader: "npm:^7.3.3"
+ p-map: "npm:^4.0.0"
prompts: "npm:^2.4.2"
react-dev-utils: "npm:^12.0.1"
react-helmet-async: "npm:^1.3.0"
- react-loadable: "npm:@docusaurus/react-loadable@5.5.2"
+ react-loadable: "npm:@docusaurus/react-loadable@6.0.0"
react-loadable-ssr-addon-v5-slorber: "npm:^1.0.1"
react-router: "npm:^5.3.4"
react-router-config: "npm:^5.1.1"
react-router-dom: "npm:^5.3.4"
rtl-detect: "npm:^1.0.4"
semver: "npm:^7.5.4"
- serve-handler: "npm:^6.1.5"
+ serve-handler: "npm:^6.1.6"
shelljs: "npm:^0.8.5"
- terser-webpack-plugin: "npm:^5.3.9"
tslib: "npm:^2.6.0"
update-notifier: "npm:^6.0.2"
- url-loader: "npm:^4.1.1"
- wait-on: "npm:^7.0.1"
- webpack: "npm:^5.88.1"
- webpack-bundle-analyzer: "npm:^4.9.0"
- webpack-dev-server: "npm:^4.15.1"
- webpack-merge: "npm:^5.9.0"
- webpackbar: "npm:^5.0.2"
+ webpack: "npm:^5.95.0"
+ webpack-bundle-analyzer: "npm:^4.10.2"
+ webpack-dev-server: "npm:^4.15.2"
+ webpack-merge: "npm:^6.0.1"
peerDependencies:
+ "@mdx-js/react": ^3.0.0
react: ^18.0.0
react-dom: ^18.0.0
bin:
docusaurus: bin/docusaurus.mjs
- checksum: f9d538d8aa49d37a3167a12f17cc89ba64d5b96d5c034c7af36f028a9aa9f926a5372e52c7ce7ef9e2a33ddc96a54d53d45d93f76d86a4f10717b06eef783c4c
+ checksum: e23c6e84b499737f32a3ca8f97c0b91947eff9da410d925eafbf79f3c426cd1ad54fb24970883e2e04c95290a0685ed33db7df296ea1ca8fe8bb92897f247b9a
languageName: node
linkType: hard
-"@docusaurus/cssnano-preset@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/cssnano-preset@npm:3.0.0"
+"@docusaurus/cssnano-preset@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/cssnano-preset@npm:3.6.1"
dependencies:
- cssnano-preset-advanced: "npm:^5.3.10"
- postcss: "npm:^8.4.26"
- postcss-sort-media-queries: "npm:^4.4.1"
+ cssnano-preset-advanced: "npm:^6.1.2"
+ postcss: "npm:^8.4.38"
+ postcss-sort-media-queries: "npm:^5.2.0"
tslib: "npm:^2.6.0"
- checksum: 60670013de7f504d6c1722a800f72b2cd6aa30a8a2119f0d36b003b65eeee4e5e52bcbbc57d0cd49ef7f4813dc042848f700676f99fae7ef049f6e97cd2b0652
+ checksum: e6aa2f8d08f0e1b8b4db80a52ffbcccb5fa7940ec85be4dd072bcc15d7730ea2343a2df6ecfa3df0a2ad7f2354f811b67306871281f78930a7927d5ad2184dcd
languageName: node
linkType: hard
-"@docusaurus/logger@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/logger@npm:3.0.0"
+"@docusaurus/faster@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/faster@npm:3.6.1"
+ dependencies:
+ "@docusaurus/types": "npm:3.6.1"
+ "@rspack/core": "npm:^1.0.14"
+ "@swc/core": "npm:^1.7.39"
+ "@swc/html": "npm:^1.7.39"
+ browserslist: "npm:^4.24.2"
+ lightningcss: "npm:^1.27.0"
+ swc-loader: "npm:^0.2.6"
+ tslib: "npm:^2.6.0"
+ webpack: "npm:^5.95.0"
+ checksum: 57982aaaa8d9d0c2d6c6339fa62c0167f3e4d2ab4d0786eb68e3144634971d6f1697641ed44f688ca6c434892976b54b88ef4344c0151eec8747fe2e6226a556
+ languageName: node
+ linkType: hard
+
+"@docusaurus/logger@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/logger@npm:3.6.1"
dependencies:
chalk: "npm:^4.1.2"
tslib: "npm:^2.6.0"
- checksum: 493732d2e2f03824728bdd1dba5c5515dbad81be12864f4570aff999f782d2f9fa1b47155d105e309f88a93334977dd70d964a336cc4ffb26d76d13a18ef7362
+ checksum: 536dd850331465891994a12926ef0b9387b28f8b007180d4fc9d7ddb6f306dad2e5157e9dda8138613842357db1227dd0ba41c2d1da5e8e8d29166347b9d8899
languageName: node
linkType: hard
-"@docusaurus/mdx-loader@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/mdx-loader@npm:3.0.0"
+"@docusaurus/mdx-loader@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/mdx-loader@npm:3.6.1"
dependencies:
- "@babel/parser": "npm:^7.22.7"
- "@babel/traverse": "npm:^7.22.8"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
"@mdx-js/mdx": "npm:^3.0.0"
"@slorber/remark-comment": "npm:^1.0.0"
escape-html: "npm:^1.0.3"
@@ -1839,38 +1766,37 @@ __metadata:
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 35d62c4128b639880b3037027348f98adc10dcd837300e9876a5a03711ffcf969cd626d5ef1fe10cf139d14e26c0f7b3bfb5e00d83992b4559b0eebc05e4e8c7
+ checksum: 569c90a643507fe6032fc08e88a1dcfba3207239de3bb0e3e4d24d5efe86099353e2471ead3241d1ba23f22afeb6d4c054091158e7bc600a27e0945b87a865d7
languageName: node
linkType: hard
-"@docusaurus/module-type-aliases@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/module-type-aliases@npm:3.0.0"
+"@docusaurus/module-type-aliases@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/module-type-aliases@npm:3.6.1"
dependencies:
- "@docusaurus/react-loadable": "npm:5.5.2"
- "@docusaurus/types": "npm:3.0.0"
+ "@docusaurus/types": "npm:3.6.1"
"@types/history": "npm:^4.7.11"
"@types/react": "npm:*"
"@types/react-router-config": "npm:*"
"@types/react-router-dom": "npm:*"
react-helmet-async: "npm:*"
- react-loadable: "npm:@docusaurus/react-loadable@5.5.2"
+ react-loadable: "npm:@docusaurus/react-loadable@6.0.0"
peerDependencies:
react: "*"
react-dom: "*"
- checksum: 84ab728b34be8551ec3f915388bc059e918d542ff397058d2e9174f223f5497e647815bfc921098baab87aff402a1fa8fbe1bbe77cf49a7770161e3def2df07a
+ checksum: 006a5414234bb26300e9240de519ba5bf53198869df953f090d9a28ccee99850e1a7384dffccb865ccd513bf1d090a8ab5887fa7583b921df1279b99613aa0b7
languageName: node
linkType: hard
-"@docusaurus/plugin-client-redirects@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-client-redirects@npm:3.0.0"
+"@docusaurus/plugin-client-redirects@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-client-redirects@npm:3.6.1"
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-common": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
eta: "npm:^2.2.0"
fs-extra: "npm:^11.1.1"
lodash: "npm:^4.17.21"
@@ -1878,22 +1804,23 @@ __metadata:
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 6664e47fc168c0b31428e17e71df70ebee796836f83d2e26bfbb3ac030a4a7195602c2fcf67f9e0a5e634e37cf287c992b61802c25da2e285844f0f5ee33c274
+ checksum: 274f5e13806c766e90e7fa001c166d6063318cc5e166f77804b27afd2beb75405166bf0d37322b3adb1ffe3c3090a81b3ac4e07d4e8bca9559906eaff13dec35
languageName: node
linkType: hard
-"@docusaurus/plugin-content-blog@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-content-blog@npm:3.0.0"
- dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/mdx-loader": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-common": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
- cheerio: "npm:^1.0.0-rc.12"
+"@docusaurus/plugin-content-blog@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-content-blog@npm:3.6.1"
+ dependencies:
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/mdx-loader": "npm:3.6.1"
+ "@docusaurus/theme-common": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
+ cheerio: "npm:1.0.0-rc.12"
feed: "npm:^4.2.2"
fs-extra: "npm:^11.1.1"
lodash: "npm:^4.17.21"
@@ -1904,23 +1831,26 @@ __metadata:
utility-types: "npm:^3.10.0"
webpack: "npm:^5.88.1"
peerDependencies:
+ "@docusaurus/plugin-content-docs": "*"
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 2e2b19cfae6d5739f1499c37f15c36307e9eea82317ad557656058a1e6d4df59d7c6e882ef8b382ef60d64762709d0d7e9454487b5a9ab980b9cf05222d78b3a
+ checksum: baf9b30cba055367ee91f9cb2db918ab311a17614f51b4aaf7bde67764d0ec61cdd7fb39b0720f87cf781dcf67fcbf79ad19c7db120fbdcad9fe2d0b9d2e961d
languageName: node
linkType: hard
-"@docusaurus/plugin-content-docs@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-content-docs@npm:3.0.0"
- dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/mdx-loader": "npm:3.0.0"
- "@docusaurus/module-type-aliases": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+"@docusaurus/plugin-content-docs@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-content-docs@npm:3.6.1"
+ dependencies:
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/mdx-loader": "npm:3.6.1"
+ "@docusaurus/module-type-aliases": "npm:3.6.1"
+ "@docusaurus/theme-common": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
"@types/react-router-config": "npm:^5.0.7"
combine-promises: "npm:^1.1.0"
fs-extra: "npm:^11.1.1"
@@ -1932,185 +1862,174 @@ __metadata:
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: e22a6e6f0a7647c47538dd89ef21749f5adece6a3f64a335bd0bd622e3669fa6e3b6d47ea5da45cb9a1ac885754dd4f1b75eb4a2c9ddb69a027eda7f19c22509
+ checksum: f072637f2af821df47912057b7de2dbbd85abe0a4ed2ae16a226ab60641851203700250b2b2a1b6559d844ea790e34143709a3ca1c53a88769740dd636466881
languageName: node
linkType: hard
-"@docusaurus/plugin-content-pages@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-content-pages@npm:3.0.0"
+"@docusaurus/plugin-content-pages@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-content-pages@npm:3.6.1"
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/mdx-loader": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/mdx-loader": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
fs-extra: "npm:^11.1.1"
tslib: "npm:^2.6.0"
webpack: "npm:^5.88.1"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 297778d86562c5e3d30793fccf78bc283a2b92f0b87b18b8183fa7618beeb8eeeaf50eb46155467b96a27aa3e7c9e5650c26add6f9b48da6a483a220ce79a4fe
+ checksum: 439d696158b4aa549739e28915604dff64623eb445e77f633b33fb644d995a875d93fd93505ec534b88c97c94eda45256b9112c0f438d95118c0a0a3359deafd
languageName: node
linkType: hard
-"@docusaurus/plugin-debug@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-debug@npm:3.0.0"
+"@docusaurus/plugin-debug@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-debug@npm:3.6.1"
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@microlink/react-json-view": "npm:^1.22.2"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
fs-extra: "npm:^11.1.1"
+ react-json-view-lite: "npm:^1.2.0"
tslib: "npm:^2.6.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: f1a97c5f07b7316ee85fc93c18b4d519fc76c5dbaaa8ab609feddffec647b52fe7b8f176bb2b552186dc39c8dd920702d0353437a48cb0d023907d0736722e87
+ checksum: 447daab549cd76fcdd5b1a8a113748b0e7f18bc5d30c03ee8d401a02c5d44145c02d47833b3c16174426db956a102d11f57b2dd37c1d9c5c46bf51c083b11237
languageName: node
linkType: hard
-"@docusaurus/plugin-google-analytics@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-google-analytics@npm:3.0.0"
+"@docusaurus/plugin-google-analytics@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-google-analytics@npm:3.6.1"
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
tslib: "npm:^2.6.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 17e7196724854e963010c75bb6dd4aa03b15c3491a90ade7d6cbd308b1ed02e630c114c5d89cdd30e3c230bddfbbb16cbf4ec7405cf99363778dcef6372f1d8f
+ checksum: ab84513ceab61cb281959cae090ff8e8c88951908f55b6cba4dfbc7d9a73ae99b35b7f17f202f65200d36b65bb602447f7aec4b6ce5b01183e9c8388ae817d44
languageName: node
linkType: hard
-"@docusaurus/plugin-google-gtag@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-google-gtag@npm:3.0.0"
+"@docusaurus/plugin-google-gtag@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-google-gtag@npm:3.6.1"
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
"@types/gtag.js": "npm:^0.0.12"
tslib: "npm:^2.6.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: f92e0537532bb9e5f3fd942920763ff5cbc8d29cff18adfeccd08cf91f370823badc439244ad9305f19256845df6b10fc393d82e3793e6dc4cdefce085d1c890
+ checksum: c3328c6ab28410c89d825722039ab843c1a8b9d2523be03aef2cc5238ce203d8b1082eb4f25206219181f8f46ca64129f8dd27775154692a69180dda44454f8b
languageName: node
linkType: hard
-"@docusaurus/plugin-google-tag-manager@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-google-tag-manager@npm:3.0.0"
+"@docusaurus/plugin-google-tag-manager@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-google-tag-manager@npm:3.6.1"
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
tslib: "npm:^2.6.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: ef4bdde396ca738c7becd5f1904cd75fe4cbdf7c82d84ee3af260b7b47b4faabfef6f3b3a044d6c8b8011a4bd2ee8639cb99211041ba7181017638a194bbb7e8
+ checksum: 7e011681c83a64abed7b243a8a16c98bbfde59da5c2e62c4ee878405344eb89c126fb6949371a3542aca3cb6df5824e5ce39cedd9de8cfc9f23c3b46b632832d
languageName: node
linkType: hard
-"@docusaurus/plugin-sitemap@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/plugin-sitemap@npm:3.0.0"
- dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-common": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+"@docusaurus/plugin-sitemap@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/plugin-sitemap@npm:3.6.1"
+ dependencies:
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
fs-extra: "npm:^11.1.1"
sitemap: "npm:^7.1.1"
tslib: "npm:^2.6.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: bb29c677e213df381c5484420bfd5738ae77c51a1bf91e2c46b90a00264257672da4b5a26fb7e2d8818b515edd5d3261a341b0403cf7e3dbffac532a1c5a70ff
+ checksum: a11bac07a8aef01b696a879a2de64bccb80ca32c44809a2e58419a5d7d007d6c20cdbd7302e651d70b845a03175c9bd34d2620a50f0c5a7bab2e3e060abdf805
languageName: node
linkType: hard
-"@docusaurus/preset-classic@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/preset-classic@npm:3.0.0"
- dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/plugin-content-blog": "npm:3.0.0"
- "@docusaurus/plugin-content-docs": "npm:3.0.0"
- "@docusaurus/plugin-content-pages": "npm:3.0.0"
- "@docusaurus/plugin-debug": "npm:3.0.0"
- "@docusaurus/plugin-google-analytics": "npm:3.0.0"
- "@docusaurus/plugin-google-gtag": "npm:3.0.0"
- "@docusaurus/plugin-google-tag-manager": "npm:3.0.0"
- "@docusaurus/plugin-sitemap": "npm:3.0.0"
- "@docusaurus/theme-classic": "npm:3.0.0"
- "@docusaurus/theme-common": "npm:3.0.0"
- "@docusaurus/theme-search-algolia": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
+"@docusaurus/preset-classic@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/preset-classic@npm:3.6.1"
+ dependencies:
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/plugin-content-blog": "npm:3.6.1"
+ "@docusaurus/plugin-content-docs": "npm:3.6.1"
+ "@docusaurus/plugin-content-pages": "npm:3.6.1"
+ "@docusaurus/plugin-debug": "npm:3.6.1"
+ "@docusaurus/plugin-google-analytics": "npm:3.6.1"
+ "@docusaurus/plugin-google-gtag": "npm:3.6.1"
+ "@docusaurus/plugin-google-tag-manager": "npm:3.6.1"
+ "@docusaurus/plugin-sitemap": "npm:3.6.1"
+ "@docusaurus/theme-classic": "npm:3.6.1"
+ "@docusaurus/theme-common": "npm:3.6.1"
+ "@docusaurus/theme-search-algolia": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 5630380413afbf57c3acbf2fb481ad9d54b0ed599fb7c778ac0f005203c7ceb98e231e5a83918dbe16942608b863f3ff2bc13ffbb0b251003fad986869dbc05a
+ checksum: abac722eb29816561f1c27e19a42bb90f0d2cde2a24c877c8d5d6c9dd1f28a11746027ad61b15b108cc1731a89f7d6fd9ebe8967a3639a3dd0bd0fe7f0e08740
languageName: node
linkType: hard
-"@docusaurus/react-loadable@npm:5.5.2, react-loadable@npm:@docusaurus/react-loadable@5.5.2":
- version: 5.5.2
- resolution: "@docusaurus/react-loadable@npm:5.5.2"
- dependencies:
- "@types/react": "npm:*"
- prop-types: "npm:^15.6.2"
- peerDependencies:
- react: "*"
- checksum: 3f6a335d55c811c4fd40300ff0d87ae88f44f96e9c43a4c3f54f1c19b7a55bae601e43d66f797074e204699fd6abb69affa65fc4c5a819e8f1c2adb8a912da46
- languageName: node
- linkType: hard
-
-"@docusaurus/remark-plugin-npm2yarn@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/remark-plugin-npm2yarn@npm:3.0.0"
+"@docusaurus/remark-plugin-npm2yarn@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/remark-plugin-npm2yarn@npm:3.6.1"
dependencies:
mdast-util-mdx: "npm:^3.0.0"
- npm-to-yarn: "npm:^2.0.0"
+ npm-to-yarn: "npm:^3.0.0"
tslib: "npm:^2.6.0"
unified: "npm:^11.0.3"
unist-util-visit: "npm:^5.0.0"
- checksum: 48f0db878f2074d30fd461949b05de4cd43d687b8f35cf464c94b76add32cc37b5288db05294fde0d014c3dbf40c85ea3fe59d897815cd91a6e4348c3fae355b
- languageName: node
- linkType: hard
-
-"@docusaurus/theme-classic@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/theme-classic@npm:3.0.0"
- dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/mdx-loader": "npm:3.0.0"
- "@docusaurus/module-type-aliases": "npm:3.0.0"
- "@docusaurus/plugin-content-blog": "npm:3.0.0"
- "@docusaurus/plugin-content-docs": "npm:3.0.0"
- "@docusaurus/plugin-content-pages": "npm:3.0.0"
- "@docusaurus/theme-common": "npm:3.0.0"
- "@docusaurus/theme-translations": "npm:3.0.0"
- "@docusaurus/types": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-common": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ checksum: d85d98eb5657418bea2c0eeb4e45fbf8ed0b32f2e9ca5b2766a5fd07039227e1514b8c542846e49a0c23b33456594d391b0ff5fc4caa5dde8e41a6d0bd4b42db
+ languageName: node
+ linkType: hard
+
+"@docusaurus/theme-classic@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/theme-classic@npm:3.6.1"
+ dependencies:
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/mdx-loader": "npm:3.6.1"
+ "@docusaurus/module-type-aliases": "npm:3.6.1"
+ "@docusaurus/plugin-content-blog": "npm:3.6.1"
+ "@docusaurus/plugin-content-docs": "npm:3.6.1"
+ "@docusaurus/plugin-content-pages": "npm:3.6.1"
+ "@docusaurus/theme-common": "npm:3.6.1"
+ "@docusaurus/theme-translations": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
"@mdx-js/react": "npm:^3.0.0"
- clsx: "npm:^1.2.1"
+ clsx: "npm:^2.0.0"
copy-text-to-clipboard: "npm:^3.2.0"
- infima: "npm:0.2.0-alpha.43"
+ infima: "npm:0.2.0-alpha.45"
lodash: "npm:^4.17.21"
nprogress: "npm:^0.2.0"
postcss: "npm:^8.4.26"
- prism-react-renderer: "npm:^2.1.0"
+ prism-react-renderer: "npm:^2.3.0"
prismjs: "npm:^1.29.0"
react-router-dom: "npm:^5.3.4"
rtlcss: "npm:^4.1.0"
@@ -2119,51 +2038,49 @@ __metadata:
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 226859b735d1aad7649c9bd3c0a1e12524f367643cf653497945e5e99b2bd97a57c1b95a285ee631ad1464e092186aede5e84ac8f3c6fa500ccaae922d6d9e3a
+ checksum: 4836ebf9db4b6044af0e20435a5778bc001868a20c9a54fd2b194559755c454d03552e3c46edba1329d7cd7d89ea6a5c13ded19206531899974b8ee193551dd6
languageName: node
linkType: hard
-"@docusaurus/theme-common@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/theme-common@npm:3.0.0"
- dependencies:
- "@docusaurus/mdx-loader": "npm:3.0.0"
- "@docusaurus/module-type-aliases": "npm:3.0.0"
- "@docusaurus/plugin-content-blog": "npm:3.0.0"
- "@docusaurus/plugin-content-docs": "npm:3.0.0"
- "@docusaurus/plugin-content-pages": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-common": "npm:3.0.0"
+"@docusaurus/theme-common@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/theme-common@npm:3.6.1"
+ dependencies:
+ "@docusaurus/mdx-loader": "npm:3.6.1"
+ "@docusaurus/module-type-aliases": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
"@types/history": "npm:^4.7.11"
"@types/react": "npm:*"
"@types/react-router-config": "npm:*"
- clsx: "npm:^1.2.1"
+ clsx: "npm:^2.0.0"
parse-numeric-range: "npm:^1.3.0"
- prism-react-renderer: "npm:^2.1.0"
+ prism-react-renderer: "npm:^2.3.0"
tslib: "npm:^2.6.0"
utility-types: "npm:^3.10.0"
peerDependencies:
+ "@docusaurus/plugin-content-docs": "*"
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 89da7885651bf38667df6cb0e140581030a1af20e21c7ea5f9da7b2cdd5293619a14a0d73e12d841836c37ec95173b9fce45c17025fb59ec1cd9a30a7a9a9a3d
+ checksum: 4f3739fe3af5292b389b811f617a4da7f3617d940f9e09349bfaf5ce823941e732651fe45a8f9d9f3c6cb444cd788b4e1952d18f56c78531299635df840974ce
languageName: node
linkType: hard
-"@docusaurus/theme-search-algolia@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/theme-search-algolia@npm:3.0.0"
+"@docusaurus/theme-search-algolia@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/theme-search-algolia@npm:3.6.1"
dependencies:
"@docsearch/react": "npm:^3.5.2"
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/plugin-content-docs": "npm:3.0.0"
- "@docusaurus/theme-common": "npm:3.0.0"
- "@docusaurus/theme-translations": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
- "@docusaurus/utils-validation": "npm:3.0.0"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/plugin-content-docs": "npm:3.6.1"
+ "@docusaurus/theme-common": "npm:3.6.1"
+ "@docusaurus/theme-translations": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-validation": "npm:3.6.1"
algoliasearch: "npm:^4.18.0"
algoliasearch-helper: "npm:^3.13.3"
- clsx: "npm:^1.2.1"
+ clsx: "npm:^2.0.0"
eta: "npm:^2.2.0"
fs-extra: "npm:^11.1.1"
lodash: "npm:^4.17.21"
@@ -2172,72 +2089,74 @@ __metadata:
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: d90b846e9dce18a530cb9c0be9fb885667ebe5947d2ef92d8f385870fc6de837e627ef9ad6373444b4974e0dc6d093ca5d91f5eafbf024da180bb520fc57fea1
+ checksum: 5295f416ce10a68e0f71e4ecfad5f4f6071a3d1d799220654fb8981ac66322a5c1f5c9bb7871d62b6bc6b73d7656d4cbd2b165cb51f1a7cb6ca65136ac1a57ba
languageName: node
linkType: hard
-"@docusaurus/theme-translations@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/theme-translations@npm:3.0.0"
+"@docusaurus/theme-translations@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/theme-translations@npm:3.6.1"
dependencies:
fs-extra: "npm:^11.1.1"
tslib: "npm:^2.6.0"
- checksum: b47d3e5068850c895d9826303992e6e8381f861027b3e761510d6ae47a5498d8534b47c19d9aea212cc2707ea4b62b455700dd7bc2c1fa9a271e11e0ef823503
+ checksum: ed8b2665a0fb62b8d338aeae177d4661294e4c6e9ba3d19d78dbea8f40a374658838d8be9d6f7271205265ddeea20399db6427f9d20db226dc3d5bb58b736b8a
languageName: node
linkType: hard
-"@docusaurus/types@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/types@npm:3.0.0"
+"@docusaurus/types@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/types@npm:3.6.1"
dependencies:
+ "@mdx-js/mdx": "npm:^3.0.0"
"@types/history": "npm:^4.7.11"
"@types/react": "npm:*"
commander: "npm:^5.1.0"
joi: "npm:^17.9.2"
react-helmet-async: "npm:^1.3.0"
utility-types: "npm:^3.10.0"
- webpack: "npm:^5.88.1"
+ webpack: "npm:^5.95.0"
webpack-merge: "npm:^5.9.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 3fdb6ccd795924cfa3fc33f37cd3224f1b41337927e068444c82c70059c4f2182d9d60bd9955d8215a4b5f0b6b619b8afbedbb5e90092c40acf3db53e092fd2b
+ checksum: d73e118e0fbcbb15fcb908dddaf81c977c5ded53dacce181f7736a234b1b0b930b9dae8847e7951245754b3c5f5b9c0d8002f020a56ad8ba32587f8723209776
languageName: node
linkType: hard
-"@docusaurus/utils-common@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/utils-common@npm:3.0.0"
+"@docusaurus/utils-common@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/utils-common@npm:3.6.1"
dependencies:
+ "@docusaurus/types": "npm:3.6.1"
tslib: "npm:^2.6.0"
- peerDependencies:
- "@docusaurus/types": "*"
- peerDependenciesMeta:
- "@docusaurus/types":
- optional: true
- checksum: 072edfd6a2722ee4b3988f107362e17bb9f05024851d033b201f468a2d363539f962772ec8b5f1399faa38586c5decf080a0ffb2fd981ed5a18ddeb7a982e9a7
+ checksum: 3a548139b5be365e380df2b90ae3763372f81f78e72ec078f15753477d2cc31218360dcdac0137f435203dff1292b26bfee5f72f867c4f6bc2064a8e07c06ef8
languageName: node
linkType: hard
-"@docusaurus/utils-validation@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/utils-validation@npm:3.0.0"
+"@docusaurus/utils-validation@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/utils-validation@npm:3.6.1"
dependencies:
- "@docusaurus/logger": "npm:3.0.0"
- "@docusaurus/utils": "npm:3.0.0"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/utils": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ fs-extra: "npm:^11.2.0"
joi: "npm:^17.9.2"
js-yaml: "npm:^4.1.0"
+ lodash: "npm:^4.17.21"
tslib: "npm:^2.6.0"
- checksum: 80cd186db7d2deb46580200045b8c411e66980fa7e10b347a15d81e5f99e2a91099a34a629beda69536c6182e1f29c0ca9102bcf240a2684ec0fe7517e0e61ce
+ checksum: fd8852c4c1ce0fe5765f8c00ceaee683dacc07a8a54e9ac63a75902f2673c5b595798ef5c530f7a3bc22ae3b5619b553077f82c81c825fd035b46f4c2298a3d3
languageName: node
linkType: hard
-"@docusaurus/utils@npm:3.0.0":
- version: 3.0.0
- resolution: "@docusaurus/utils@npm:3.0.0"
+"@docusaurus/utils@npm:3.6.1":
+ version: 3.6.1
+ resolution: "@docusaurus/utils@npm:3.6.1"
dependencies:
- "@docusaurus/logger": "npm:3.0.0"
- "@svgr/webpack": "npm:^6.5.1"
+ "@docusaurus/logger": "npm:3.6.1"
+ "@docusaurus/types": "npm:3.6.1"
+ "@docusaurus/utils-common": "npm:3.6.1"
+ "@svgr/webpack": "npm:^8.1.0"
escape-string-regexp: "npm:^4.0.0"
file-loader: "npm:^6.2.0"
fs-extra: "npm:^11.1.1"
@@ -2248,17 +2167,14 @@ __metadata:
js-yaml: "npm:^4.1.0"
lodash: "npm:^4.17.21"
micromatch: "npm:^4.0.5"
+ prompts: "npm:^2.4.2"
resolve-pathname: "npm:^3.0.0"
shelljs: "npm:^0.8.5"
tslib: "npm:^2.6.0"
url-loader: "npm:^4.1.1"
+ utility-types: "npm:^3.10.0"
webpack: "npm:^5.88.1"
- peerDependencies:
- "@docusaurus/types": "*"
- peerDependenciesMeta:
- "@docusaurus/types":
- optional: true
- checksum: 74095238c5704cb29de0b700981ea237018788de1340049dc9f03d5d15b0894ec3edf040da8faffc5ccf4a8cd5f6f3d974287b3cc1ab4818d3894c787bbccd5a
+ checksum: a97131caa6622df9d86378394d334f0751ea330361ed88b286a1accb3e5106030839d353eab9ab2ee88a615da1730da851c34783587b994480fc9f514413fc4a
languageName: node
linkType: hard
@@ -2315,14 +2231,14 @@ __metadata:
languageName: node
linkType: hard
-"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2":
- version: 0.3.3
- resolution: "@jridgewell/gen-mapping@npm:0.3.3"
+"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.5":
+ version: 0.3.5
+ resolution: "@jridgewell/gen-mapping@npm:0.3.5"
dependencies:
- "@jridgewell/set-array": "npm:^1.0.1"
+ "@jridgewell/set-array": "npm:^1.2.1"
"@jridgewell/sourcemap-codec": "npm:^1.4.10"
- "@jridgewell/trace-mapping": "npm:^0.3.9"
- checksum: 376fc11cf5a967318ba3ddd9d8e91be528eab6af66810a713c49b0c3f8dc67e9949452c51c38ab1b19aa618fb5e8594da5a249977e26b1e7fea1ee5a1fcacc74
+ "@jridgewell/trace-mapping": "npm:^0.3.24"
+ checksum: 1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb
languageName: node
linkType: hard
@@ -2333,10 +2249,10 @@ __metadata:
languageName: node
linkType: hard
-"@jridgewell/set-array@npm:^1.0.1":
- version: 1.1.2
- resolution: "@jridgewell/set-array@npm:1.1.2"
- checksum: bc7ab4c4c00470de4e7562ecac3c0c84f53e7ee8a711e546d67c47da7febe7c45cd67d4d84ee3c9b2c05ae8e872656cdded8a707a283d30bd54fbc65aef821ab
+"@jridgewell/set-array@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "@jridgewell/set-array@npm:1.2.1"
+ checksum: 2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4
languageName: node
linkType: hard
@@ -2357,7 +2273,7 @@ __metadata:
languageName: node
linkType: hard
-"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9":
+"@jridgewell/trace-mapping@npm:^0.3.17":
version: 0.3.20
resolution: "@jridgewell/trace-mapping@npm:0.3.20"
dependencies:
@@ -2367,6 +2283,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.9":
+ version: 0.3.25
+ resolution: "@jridgewell/trace-mapping@npm:0.3.25"
+ dependencies:
+ "@jridgewell/resolve-uri": "npm:^3.1.0"
+ "@jridgewell/sourcemap-codec": "npm:^1.4.14"
+ checksum: 3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4
+ languageName: node
+ linkType: hard
+
"@leichtgewicht/ip-codec@npm:^2.0.1":
version: 2.0.4
resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
@@ -2417,18 +2343,39 @@ __metadata:
languageName: node
linkType: hard
-"@microlink/react-json-view@npm:^1.22.2":
- version: 1.23.0
- resolution: "@microlink/react-json-view@npm:1.23.0"
+"@module-federation/runtime-tools@npm:0.5.1":
+ version: 0.5.1
+ resolution: "@module-federation/runtime-tools@npm:0.5.1"
dependencies:
- flux: "npm:~4.0.1"
- react-base16-styling: "npm:~0.6.0"
- react-lifecycles-compat: "npm:~3.0.4"
- react-textarea-autosize: "npm:~8.3.2"
- peerDependencies:
- react: ">= 15"
- react-dom: ">= 15"
- checksum: 6728719c49bb2c38280e1fb521a8fae676915d9724b56854430114c78da0491633758b3e146eb87ddc5ae4d881dd3afa10a66f39f15b97887604944c2d1c6360
+ "@module-federation/runtime": "npm:0.5.1"
+ "@module-federation/webpack-bundler-runtime": "npm:0.5.1"
+ checksum: fc6e8be50d6b4e9a9e9454d8c836c939eeb2bd6ed145701ef1b5dd0cb43058874404877a58182b2568ea6f216d5dae84785d3db8d867ddd4f610481a859f5d89
+ languageName: node
+ linkType: hard
+
+"@module-federation/runtime@npm:0.5.1":
+ version: 0.5.1
+ resolution: "@module-federation/runtime@npm:0.5.1"
+ dependencies:
+ "@module-federation/sdk": "npm:0.5.1"
+ checksum: f7810c7d21e22ce4689967e387298f01571503f7ec3ddfea863929eb1a673aec9de37a0a1584d039cddcb76d2c1c5c26741fdc1be1224db0024ea9e939d24429
+ languageName: node
+ linkType: hard
+
+"@module-federation/sdk@npm:0.5.1":
+ version: 0.5.1
+ resolution: "@module-federation/sdk@npm:0.5.1"
+ checksum: 63c7d00358e6f43e10b3f216808f2489d78059ac151e3acfff5f0744ef531505d716563330d35e2b2998c58f5f28f09ace7b4ee3162685a31f7908a6d41e6834
+ languageName: node
+ linkType: hard
+
+"@module-federation/webpack-bundler-runtime@npm:0.5.1":
+ version: 0.5.1
+ resolution: "@module-federation/webpack-bundler-runtime@npm:0.5.1"
+ dependencies:
+ "@module-federation/runtime": "npm:0.5.1"
+ "@module-federation/sdk": "npm:0.5.1"
+ checksum: 6a2423efe16a63d7059face6af07d282efc1cfa04a16397d1b354c5eb8541ffa314d32d4da8f7863e0b14f92b0f67270f313c2797e13f63f635bc94988115abf
languageName: node
linkType: hard
@@ -2481,64 +2428,63 @@ __metadata:
languageName: node
linkType: hard
-"@octokit/endpoint@npm:^9.0.0":
- version: 9.0.2
- resolution: "@octokit/endpoint@npm:9.0.2"
+"@octokit/endpoint@npm:^9.0.1":
+ version: 9.0.5
+ resolution: "@octokit/endpoint@npm:9.0.5"
dependencies:
- "@octokit/types": "npm:^12.0.0"
- is-plain-object: "npm:^5.0.0"
+ "@octokit/types": "npm:^13.1.0"
universal-user-agent: "npm:^6.0.0"
- checksum: 325ad5f2f4aaba0ef90436809dad423faf5f373dac5754af050bd117e70b6ded3a370745dfa4c860a8aa8161bc31cd7706f4b647aef8602f23a355d0cfbe3907
+ checksum: e9bbb2111abe691c146075abb1b6f724a9b77fa8bfefdaaa82b8ebad6c8790e949f2367bb0b79800fef93ad72807513333e83e8ffba389bc85215535f63534d9
languageName: node
linkType: hard
-"@octokit/graphql@npm:^7.0.2":
- version: 7.0.2
- resolution: "@octokit/graphql@npm:7.0.2"
+"@octokit/graphql@npm:^7.1.0":
+ version: 7.1.0
+ resolution: "@octokit/graphql@npm:7.1.0"
dependencies:
- "@octokit/request": "npm:^8.0.1"
- "@octokit/types": "npm:^12.0.0"
+ "@octokit/request": "npm:^8.3.0"
+ "@octokit/types": "npm:^13.0.0"
universal-user-agent: "npm:^6.0.0"
- checksum: 96e5d6b970be60877134cc147b9249534f3a79d691b9932d731d453426fa1e1a0a36111a1b0a6ab43d61309c630903a65db5559b5c800300dc26cf588f50fea8
+ checksum: 6d50a013d151f416fc837644e394e8b8872da7b17b181da119842ca569b0971e4dfacda55af6c329b51614e436945415dd5bd75eb3652055fdb754bbcd20d9d1
languageName: node
linkType: hard
-"@octokit/openapi-types@npm:^19.0.2":
- version: 19.0.2
- resolution: "@octokit/openapi-types@npm:19.0.2"
- checksum: e003a3b7471edfa970911252c19ce9331d935699cc1e91a1e151316b585c3b2f5251bc5ba137b7e14aed8a9b3890fdf67edc5cc5af4805bf4b44f5869544e678
+"@octokit/openapi-types@npm:^22.2.0":
+ version: 22.2.0
+ resolution: "@octokit/openapi-types@npm:22.2.0"
+ checksum: a45bfc735611e836df0729f5922bbd5811d401052b972d1e3bc1278a2d2403e00f4552ce9d1f2793f77f167d212da559c5cb9f1b02c935114ad6d898779546ee
languageName: node
linkType: hard
-"@octokit/request-error@npm:^5.0.0":
- version: 5.0.1
- resolution: "@octokit/request-error@npm:5.0.1"
+"@octokit/request-error@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "@octokit/request-error@npm:5.1.0"
dependencies:
- "@octokit/types": "npm:^12.0.0"
+ "@octokit/types": "npm:^13.1.0"
deprecation: "npm:^2.0.0"
once: "npm:^1.4.0"
- checksum: e72a4627120de345b54876a1f007664095e5be9d624fce2e14fccf7668cd8f5e4929d444d8fc085d48e1fb5cd548538453974aab129a669101110d6679dce6c6
+ checksum: 61e688abce17dd020ea1e343470b9758f294bfe5432c5cb24bdb5b9b10f90ecec1ecaaa13b48df9288409e0da14252f6579a20f609af155bd61dc778718b7738
languageName: node
linkType: hard
-"@octokit/request@npm:^8.0.1":
- version: 8.1.6
- resolution: "@octokit/request@npm:8.1.6"
+"@octokit/request@npm:^8.3.0":
+ version: 8.4.0
+ resolution: "@octokit/request@npm:8.4.0"
dependencies:
- "@octokit/endpoint": "npm:^9.0.0"
- "@octokit/request-error": "npm:^5.0.0"
- "@octokit/types": "npm:^12.0.0"
+ "@octokit/endpoint": "npm:^9.0.1"
+ "@octokit/request-error": "npm:^5.1.0"
+ "@octokit/types": "npm:^13.1.0"
universal-user-agent: "npm:^6.0.0"
- checksum: ef84418e0b1f28335c105bca2b1518b04797791761024d26f80f60a528cdcf468baf9897fd34f535c42af0643a598884f882bc832e68edbfe1ea530c2df563a4
+ checksum: b857782ac2ff5387e9cc502759de73ea642c498c97d06ad2ecd8a395e4b9532d9f3bc3fc460e0d3d0e8f0d43c917a90c493e43766d37782b3979d3afffbf1b4b
languageName: node
linkType: hard
-"@octokit/types@npm:^12.0.0":
- version: 12.3.0
- resolution: "@octokit/types@npm:12.3.0"
+"@octokit/types@npm:^13.0.0, @octokit/types@npm:^13.1.0":
+ version: 13.6.1
+ resolution: "@octokit/types@npm:13.6.1"
dependencies:
- "@octokit/openapi-types": "npm:^19.0.2"
- checksum: 083f33d8df492ef4029b94b1b5ac5ac422bc5787fe6c086d4738007f207e2b8fa523a1397ecc902d808ba235ec7bf7e38f4659cae177d40002e43eadf3b6f3d8
+ "@octokit/openapi-types": "npm:^22.2.0"
+ checksum: 891334b5786ba6aef953384cec05d53e05132dd577c0c22db124d55eaa69609362d1e3147853b46e91bf226e046ba24d615c55214c8f8f4e7c3a5c38429b38e9
languageName: node
linkType: hard
@@ -2583,28 +2529,152 @@ __metadata:
languageName: node
linkType: hard
-"@react-navigation/core@npm:^7.0.0-alpha.2":
- version: 7.0.0-alpha.6
- resolution: "@react-navigation/core@npm:7.0.0-alpha.6"
+"@react-navigation/core@npm:^7.0.4":
+ version: 7.0.4
+ resolution: "@react-navigation/core@npm:7.0.4"
dependencies:
- "@react-navigation/routers": "npm:^7.0.0-alpha.4"
+ "@react-navigation/routers": "npm:^7.0.0"
escape-string-regexp: "npm:^4.0.0"
- nanoid: "npm:3.3.6"
+ nanoid: "npm:3.3.7"
query-string: "npm:^7.1.3"
react-is: "npm:^18.2.0"
- use-latest-callback: "npm:^0.1.9"
+ use-latest-callback: "npm:^0.2.1"
+ use-sync-external-store: "npm:^1.2.2"
peerDependencies:
- react: "*"
- checksum: 14bf0e9637602d94d13ff805ecdf84cda78cb54ff3a73fbad6bd3851f068ff181e9e099fa5cf55034359cbd645c8a0dcad21188201fa642da4ca863172b212ef
+ react: ">= 18.2.0"
+ checksum: 8df3fb6f3883b1e079460db4512f8e5d9f5fce0c1fa15f073837c5d38c06ccbe98495be90ad157191698b80c3745b0fc0ef6a2d648755cc07ab561c2b6376909
+ languageName: node
+ linkType: hard
+
+"@react-navigation/routers@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "@react-navigation/routers@npm:7.0.0"
+ dependencies:
+ nanoid: "npm:3.3.7"
+ checksum: 942041a477c3597be6f50188d2eba03bfdd489acf67f9ec89db577bf6ece10dfff872b890a58c9d31d92d25fa75e04f6f1cb3033e70ababedef8ebefe0c47e60
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-darwin-arm64@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-darwin-arm64@npm:1.0.14"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-darwin-x64@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-darwin-x64@npm:1.0.14"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-arm64-gnu@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-linux-arm64-gnu@npm:1.0.14"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-arm64-musl@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-linux-arm64-musl@npm:1.0.14"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-x64-gnu@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-linux-x64-gnu@npm:1.0.14"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-x64-musl@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-linux-x64-musl@npm:1.0.14"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-win32-arm64-msvc@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-win32-arm64-msvc@npm:1.0.14"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-win32-ia32-msvc@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-win32-ia32-msvc@npm:1.0.14"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-win32-x64-msvc@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding-win32-x64-msvc@npm:1.0.14"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/binding@npm:1.0.14"
+ dependencies:
+ "@rspack/binding-darwin-arm64": "npm:1.0.14"
+ "@rspack/binding-darwin-x64": "npm:1.0.14"
+ "@rspack/binding-linux-arm64-gnu": "npm:1.0.14"
+ "@rspack/binding-linux-arm64-musl": "npm:1.0.14"
+ "@rspack/binding-linux-x64-gnu": "npm:1.0.14"
+ "@rspack/binding-linux-x64-musl": "npm:1.0.14"
+ "@rspack/binding-win32-arm64-msvc": "npm:1.0.14"
+ "@rspack/binding-win32-ia32-msvc": "npm:1.0.14"
+ "@rspack/binding-win32-x64-msvc": "npm:1.0.14"
+ dependenciesMeta:
+ "@rspack/binding-darwin-arm64":
+ optional: true
+ "@rspack/binding-darwin-x64":
+ optional: true
+ "@rspack/binding-linux-arm64-gnu":
+ optional: true
+ "@rspack/binding-linux-arm64-musl":
+ optional: true
+ "@rspack/binding-linux-x64-gnu":
+ optional: true
+ "@rspack/binding-linux-x64-musl":
+ optional: true
+ "@rspack/binding-win32-arm64-msvc":
+ optional: true
+ "@rspack/binding-win32-ia32-msvc":
+ optional: true
+ "@rspack/binding-win32-x64-msvc":
+ optional: true
+ checksum: e8e6f99327486276d69a5c497aa0708f090c5ed29c62f605c0d6e4958f8f3486ef261257071b2e25895d548562bd0e93c4ac46601418ea6f0330e9ac9290290a
languageName: node
linkType: hard
-"@react-navigation/routers@npm:^7.0.0-alpha.4":
- version: 7.0.0-alpha.4
- resolution: "@react-navigation/routers@npm:7.0.0-alpha.4"
+"@rspack/core@npm:1.0.14":
+ version: 1.0.14
+ resolution: "@rspack/core@npm:1.0.14"
dependencies:
- nanoid: "npm:3.3.6"
- checksum: 9126eb7059823577d2fe94cc03b28f60bc668bebe017c47ab4ea075bec81f1b1b49b30b2f98b581458727fe0cde3ce5140c099699fe8b8a13165470d55e1898e
+ "@module-federation/runtime-tools": "npm:0.5.1"
+ "@rspack/binding": "npm:1.0.14"
+ "@rspack/lite-tapable": "npm:1.0.1"
+ caniuse-lite: "npm:^1.0.30001616"
+ peerDependencies:
+ "@swc/helpers": ">=0.5.1"
+ peerDependenciesMeta:
+ "@swc/helpers":
+ optional: true
+ checksum: c65feb69d7765b3232df2e937d2aeb56529544751c2d75c637a4e124deb6a54c170ad6eafd36ee3cbd671c661d2361543dc7af9920bbe1d82dde60d33113df4c
+ languageName: node
+ linkType: hard
+
+"@rspack/lite-tapable@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@rspack/lite-tapable@npm:1.0.1"
+ checksum: 90bb1bc414dc51ea2d0933e09f78d25584f3f50a85f4cb8228930bd29e5931bf55eff4f348a06c51dd3149fc73b8ae3920bf0ae5ae8a0c9fe1d9b404e6ecf5b7
languageName: node
linkType: hard
@@ -2652,10 +2722,10 @@ __metadata:
languageName: node
linkType: hard
-"@sindresorhus/merge-streams@npm:^1.0.0":
- version: 1.0.0
- resolution: "@sindresorhus/merge-streams@npm:1.0.0"
- checksum: 43d077170845dc621002e9730aea567e6e126e84b3bbff01b8575266efdb2c81d223939d3bec24020e53960c154b4640bef7746aeb245abd94c5d32972dd6854
+"@sindresorhus/merge-streams@npm:^2.1.0":
+ version: 2.3.0
+ resolution: "@sindresorhus/merge-streams@npm:2.3.0"
+ checksum: 69ee906f3125fb2c6bb6ec5cdd84e8827d93b49b3892bce8b62267116cc7e197b5cccf20c160a1d32c26014ecd14470a72a5e3ee37a58f1d6dadc0db1ccf3894
languageName: node
linkType: hard
@@ -2670,27 +2740,16 @@ __metadata:
languageName: node
linkType: hard
-"@slorber/static-site-generator-webpack-plugin@npm:^4.0.7":
- version: 4.0.7
- resolution: "@slorber/static-site-generator-webpack-plugin@npm:4.0.7"
- dependencies:
- eval: "npm:^0.1.8"
- p-map: "npm:^4.0.0"
- webpack-sources: "npm:^3.2.2"
- checksum: 6ba8abc2d99e8c513bb955502f9cd219c78b2c7b9b76668bf05067cf369cfa838089b52ee51c957e1e6e8442f9dd4f2bbd8df706a3c3388e9a0d41b09a895f97
- languageName: node
- linkType: hard
-
-"@svgr/babel-plugin-add-jsx-attribute@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:6.5.1"
+"@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0":
+ version: 8.0.0
+ resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: a13ed0797189d5497890530449029bec388310e260a96459e304e2729e7a2cf4d20d34f882d9a77ccce73dd3d36065afbb6987258fdff618d7d57955065a8ad4
+ checksum: a50bd0baa34faf16bcba712091f94c7f0e230431fe99a9dfc3401fa92823ad3f68495b86ab9bf9044b53839e8c416cfbb37eb3f246ff33f261e0fa9ee1779c5b
languageName: node
linkType: hard
-"@svgr/babel-plugin-remove-jsx-attribute@npm:*":
+"@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0"
peerDependencies:
@@ -2699,7 +2758,7 @@ __metadata:
languageName: node
linkType: hard
-"@svgr/babel-plugin-remove-jsx-empty-expression@npm:*":
+"@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0"
peerDependencies:
@@ -2708,132 +2767,374 @@ __metadata:
languageName: node
linkType: hard
-"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:6.5.1"
+"@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0":
+ version: 8.0.0
+ resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 318786787c9a217c33a7340c8856436858e1fffa5a6df635fedc6b9a371f3afea080ea074b9e3cfbbd9dd962ead924fde8bc9855a394c38dd60e391883a58c81
+ checksum: 004bd1892053b7e9c1b0bb14acc44e77634ec393722b87b1e4fae53e2c35122a2dd0d5c15e9070dbeec274e22e7693a2b8b48506733a8009ee92b12946fcb10a
languageName: node
linkType: hard
-"@svgr/babel-plugin-svg-dynamic-title@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:6.5.1"
+"@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0":
+ version: 8.0.0
+ resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 16ef228c793b909fec47dd7dc05c1c3c2d77a824f42055df37e141e0534081b1bc4aec6dcc51be50c221df9f262f59270fc1c379923bfd4f5db302abafabfd8d
+ checksum: 80e0a7fcf902f984c705051ca5c82ea6050ccbb70b651a8fea6d0eb5809e4dac274b49ea6be2d87f1eb9dfc0e2d6cdfffe1669ec2117f44b67a60a07d4c0b8b8
languageName: node
linkType: hard
-"@svgr/babel-plugin-svg-em-dimensions@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:6.5.1"
+"@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0":
+ version: 8.0.0
+ resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: dfdd5cbe6ae543505eaa0da69df0735b7407294c4b0504b3e74c0e7e371f1acb914eb99fd21ff39ef5bd626b3474f064a4cccc50f41b7c556ee834f9a6d6610a
+ checksum: 73e92c8277a89279745c0c500f59f083279a8dc30cd552b22981fade2a77628fb2bd2819ee505725fcd2e93f923e3790b52efcff409a159e657b46604a0b9a21
languageName: node
linkType: hard
-"@svgr/babel-plugin-transform-react-native-svg@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:6.5.1"
+"@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0":
+ version: 8.1.0
+ resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 332fbf3bbc19d938b744440dbab9c8acd8f7a2ed6bf9c4e23f40e3f2c25615a60b3bf00902a4f1f6c20b5f382a1547b3acc6f2b2d70d80e532b5d45945f1b979
+ checksum: 655ed6bc7a208ceaa4ecff0a54ccc36008c3cb31efa90d11e171cab325ebbb21aa78f09c7b65f9b3ddeda3a85f348c0c862902c48be13c14b4de165c847974e3
languageName: node
linkType: hard
-"@svgr/babel-plugin-transform-svg-component@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-plugin-transform-svg-component@npm:6.5.1"
+"@svgr/babel-plugin-transform-svg-component@npm:8.0.0":
+ version: 8.0.0
+ resolution: "@svgr/babel-plugin-transform-svg-component@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 8d9e1c7c62abce23837e53cdacc6d09bc1f1f2b0ad7322105001c097995e9aa8dca4fa41acf39148af69f342e40081c438106949fb083e997ca497cb0448f27d
+ checksum: 4ac00bb99a3db4ef05e4362f116a3c608ee365a2d26cf7318d8d41a4a5b30a02c80455cce0e62c65b60ed815b5d632bedabac2ccd4b56f998fadef5286e3ded4
languageName: node
linkType: hard
-"@svgr/babel-preset@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/babel-preset@npm:6.5.1"
+"@svgr/babel-preset@npm:8.1.0":
+ version: 8.1.0
+ resolution: "@svgr/babel-preset@npm:8.1.0"
dependencies:
- "@svgr/babel-plugin-add-jsx-attribute": "npm:^6.5.1"
- "@svgr/babel-plugin-remove-jsx-attribute": "npm:*"
- "@svgr/babel-plugin-remove-jsx-empty-expression": "npm:*"
- "@svgr/babel-plugin-replace-jsx-attribute-value": "npm:^6.5.1"
- "@svgr/babel-plugin-svg-dynamic-title": "npm:^6.5.1"
- "@svgr/babel-plugin-svg-em-dimensions": "npm:^6.5.1"
- "@svgr/babel-plugin-transform-react-native-svg": "npm:^6.5.1"
- "@svgr/babel-plugin-transform-svg-component": "npm:^6.5.1"
+ "@svgr/babel-plugin-add-jsx-attribute": "npm:8.0.0"
+ "@svgr/babel-plugin-remove-jsx-attribute": "npm:8.0.0"
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "npm:8.0.0"
+ "@svgr/babel-plugin-replace-jsx-attribute-value": "npm:8.0.0"
+ "@svgr/babel-plugin-svg-dynamic-title": "npm:8.0.0"
+ "@svgr/babel-plugin-svg-em-dimensions": "npm:8.0.0"
+ "@svgr/babel-plugin-transform-react-native-svg": "npm:8.1.0"
+ "@svgr/babel-plugin-transform-svg-component": "npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 8e8d7a0049279152f9ac308fbfd4ce74063d8a376154718cba6309bae4316318804a32201c75c5839c629f8e1e5d641a87822764000998161d0fc1de24b0374a
+ checksum: 49367d3ad0831f79b1056871b91766246f449d4d1168623af5e283fbaefce4a01d77ab00de6b045b55e956f9aae27895823198493cd232d88d3435ea4517ffc5
languageName: node
linkType: hard
-"@svgr/core@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/core@npm:6.5.1"
+"@svgr/core@npm:8.1.0":
+ version: 8.1.0
+ resolution: "@svgr/core@npm:8.1.0"
dependencies:
- "@babel/core": "npm:^7.19.6"
- "@svgr/babel-preset": "npm:^6.5.1"
- "@svgr/plugin-jsx": "npm:^6.5.1"
+ "@babel/core": "npm:^7.21.3"
+ "@svgr/babel-preset": "npm:8.1.0"
camelcase: "npm:^6.2.0"
- cosmiconfig: "npm:^7.0.1"
- checksum: 60cce11e13391171132115dcc8da592d23e51f155ebadf9b819bd1836b8c13d40aa5c30a03a7d429f65e70a71c50669b2e10c94e4922de4e58bc898275f46c05
+ cosmiconfig: "npm:^8.1.3"
+ snake-case: "npm:^3.0.4"
+ checksum: 6a2f6b1bc79bce39f66f088d468985d518005fc5147ebf4f108570a933818b5951c2cb7da230ddff4b7c8028b5a672b2d33aa2acce012b8b9770073aa5a2d041
languageName: node
linkType: hard
-"@svgr/hast-util-to-babel-ast@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/hast-util-to-babel-ast@npm:6.5.1"
+"@svgr/hast-util-to-babel-ast@npm:8.0.0":
+ version: 8.0.0
+ resolution: "@svgr/hast-util-to-babel-ast@npm:8.0.0"
dependencies:
- "@babel/types": "npm:^7.20.0"
+ "@babel/types": "npm:^7.21.3"
entities: "npm:^4.4.0"
- checksum: 18fa37b36581ba1678f5cc5a05ce0411e08df4db267f3cd900af7ffdf5bd90522f3a46465f315cd5d7345264949479133930aafdd27ce05c474e63756196256f
+ checksum: f4165b583ba9eaf6719e598977a7b3ed182f177983e55f9eb55a6a73982d81277510e9eb7ab41f255151fb9ed4edd11ac4bef95dd872f04ed64966d8c85e0f79
languageName: node
linkType: hard
-"@svgr/plugin-jsx@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/plugin-jsx@npm:6.5.1"
+"@svgr/plugin-jsx@npm:8.1.0":
+ version: 8.1.0
+ resolution: "@svgr/plugin-jsx@npm:8.1.0"
dependencies:
- "@babel/core": "npm:^7.19.6"
- "@svgr/babel-preset": "npm:^6.5.1"
- "@svgr/hast-util-to-babel-ast": "npm:^6.5.1"
+ "@babel/core": "npm:^7.21.3"
+ "@svgr/babel-preset": "npm:8.1.0"
+ "@svgr/hast-util-to-babel-ast": "npm:8.0.0"
svg-parser: "npm:^2.0.4"
peerDependencies:
- "@svgr/core": ^6.0.0
- checksum: 365da6e43ceeff6b49258fa2fbb3c880210300e4a85ba74831e92d2dc9c53e6ab8dda422dc33fb6a339803227cf8d9a0024ce769401c46fd87209abe36d5ae43
+ "@svgr/core": "*"
+ checksum: 07b4d9e00de795540bf70556fa2cc258774d01e97a12a26234c6fdf42b309beb7c10f31ee24d1a71137239347b1547b8bb5587d3a6de10669f95dcfe99cddc56
languageName: node
linkType: hard
-"@svgr/plugin-svgo@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/plugin-svgo@npm:6.5.1"
+"@svgr/plugin-svgo@npm:8.1.0":
+ version: 8.1.0
+ resolution: "@svgr/plugin-svgo@npm:8.1.0"
dependencies:
- cosmiconfig: "npm:^7.0.1"
- deepmerge: "npm:^4.2.2"
- svgo: "npm:^2.8.0"
+ cosmiconfig: "npm:^8.1.3"
+ deepmerge: "npm:^4.3.1"
+ svgo: "npm:^3.0.2"
peerDependencies:
"@svgr/core": "*"
- checksum: da40e461145af1a92fd2ec50ea64626681fa73786f218497a4b4fb85393a58812999ca2744ee33bb7ab771aa5ce9ab1dbd08a189cb3d7a89fb58fd96913ddf91
+ checksum: bfd25460f23f1548bfb8f6f3bedd6d6972c1a4f8881bd35a4f8c115218da6e999e8f9ac0ef0ed88c4e0b93fcec37f382b94c0322f4ec2b26752a89e5cc8b9d7a
languageName: node
linkType: hard
-"@svgr/webpack@npm:^6.5.1":
- version: 6.5.1
- resolution: "@svgr/webpack@npm:6.5.1"
+"@svgr/webpack@npm:^8.1.0":
+ version: 8.1.0
+ resolution: "@svgr/webpack@npm:8.1.0"
dependencies:
- "@babel/core": "npm:^7.19.6"
- "@babel/plugin-transform-react-constant-elements": "npm:^7.18.12"
- "@babel/preset-env": "npm:^7.19.4"
+ "@babel/core": "npm:^7.21.3"
+ "@babel/plugin-transform-react-constant-elements": "npm:^7.21.3"
+ "@babel/preset-env": "npm:^7.20.2"
"@babel/preset-react": "npm:^7.18.6"
- "@babel/preset-typescript": "npm:^7.18.6"
- "@svgr/core": "npm:^6.5.1"
- "@svgr/plugin-jsx": "npm:^6.5.1"
- "@svgr/plugin-svgo": "npm:^6.5.1"
- checksum: 3e9edfbc2ef3dc07b5f50c9c5ff5c951048511dff9dffb0407e6d15343849dfb36099fc7e1e3911429382cab81f7735a86ba1d6f77d21bb8f9ca33a5dec4824a
+ "@babel/preset-typescript": "npm:^7.21.0"
+ "@svgr/core": "npm:8.1.0"
+ "@svgr/plugin-jsx": "npm:8.1.0"
+ "@svgr/plugin-svgo": "npm:8.1.0"
+ checksum: 4c1cac45bd5890de8643e5a7bfb71f3bcd8b85ae5bbacf10b8ad9f939b7a98e8d601c3ada204ffb95223abf4a24beeac5a2a0d6928a52a1ab72a29da3c015c22
+ languageName: node
+ linkType: hard
+
+"@swc/core-darwin-arm64@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-darwin-arm64@npm:1.9.1"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@swc/core-darwin-x64@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-darwin-x64@npm:1.9.1"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@swc/core-linux-arm-gnueabihf@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-linux-arm-gnueabihf@npm:1.9.1"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@swc/core-linux-arm64-gnu@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-linux-arm64-gnu@npm:1.9.1"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@swc/core-linux-arm64-musl@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-linux-arm64-musl@npm:1.9.1"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@swc/core-linux-x64-gnu@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-linux-x64-gnu@npm:1.9.1"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@swc/core-linux-x64-musl@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-linux-x64-musl@npm:1.9.1"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@swc/core-win32-arm64-msvc@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-win32-arm64-msvc@npm:1.9.1"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@swc/core-win32-ia32-msvc@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-win32-ia32-msvc@npm:1.9.1"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@swc/core-win32-x64-msvc@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/core-win32-x64-msvc@npm:1.9.1"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@swc/core@npm:^1.7.39":
+ version: 1.9.1
+ resolution: "@swc/core@npm:1.9.1"
+ dependencies:
+ "@swc/core-darwin-arm64": "npm:1.9.1"
+ "@swc/core-darwin-x64": "npm:1.9.1"
+ "@swc/core-linux-arm-gnueabihf": "npm:1.9.1"
+ "@swc/core-linux-arm64-gnu": "npm:1.9.1"
+ "@swc/core-linux-arm64-musl": "npm:1.9.1"
+ "@swc/core-linux-x64-gnu": "npm:1.9.1"
+ "@swc/core-linux-x64-musl": "npm:1.9.1"
+ "@swc/core-win32-arm64-msvc": "npm:1.9.1"
+ "@swc/core-win32-ia32-msvc": "npm:1.9.1"
+ "@swc/core-win32-x64-msvc": "npm:1.9.1"
+ "@swc/counter": "npm:^0.1.3"
+ "@swc/types": "npm:^0.1.14"
+ peerDependencies:
+ "@swc/helpers": "*"
+ dependenciesMeta:
+ "@swc/core-darwin-arm64":
+ optional: true
+ "@swc/core-darwin-x64":
+ optional: true
+ "@swc/core-linux-arm-gnueabihf":
+ optional: true
+ "@swc/core-linux-arm64-gnu":
+ optional: true
+ "@swc/core-linux-arm64-musl":
+ optional: true
+ "@swc/core-linux-x64-gnu":
+ optional: true
+ "@swc/core-linux-x64-musl":
+ optional: true
+ "@swc/core-win32-arm64-msvc":
+ optional: true
+ "@swc/core-win32-ia32-msvc":
+ optional: true
+ "@swc/core-win32-x64-msvc":
+ optional: true
+ peerDependenciesMeta:
+ "@swc/helpers":
+ optional: true
+ checksum: 7b9a3da9bdd95216b031739ebe35983e69f17284809a62706c93edfd30ede0732060d944db23007aca9aebbc49859eb5784454c8882ae6fd04eb8bd15ac6a247
+ languageName: node
+ linkType: hard
+
+"@swc/counter@npm:^0.1.3":
+ version: 0.1.3
+ resolution: "@swc/counter@npm:0.1.3"
+ checksum: 8424f60f6bf8694cfd2a9bca45845bce29f26105cda8cf19cdb9fd3e78dc6338699e4db77a89ae449260bafa1cc6bec307e81e7fb96dbf7dcfce0eea55151356
+ languageName: node
+ linkType: hard
+
+"@swc/html-darwin-arm64@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-darwin-arm64@npm:1.9.1"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@swc/html-darwin-x64@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-darwin-x64@npm:1.9.1"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@swc/html-linux-arm-gnueabihf@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-linux-arm-gnueabihf@npm:1.9.1"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@swc/html-linux-arm64-gnu@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-linux-arm64-gnu@npm:1.9.1"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@swc/html-linux-arm64-musl@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-linux-arm64-musl@npm:1.9.1"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@swc/html-linux-x64-gnu@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-linux-x64-gnu@npm:1.9.1"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@swc/html-linux-x64-musl@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-linux-x64-musl@npm:1.9.1"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@swc/html-win32-arm64-msvc@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-win32-arm64-msvc@npm:1.9.1"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@swc/html-win32-ia32-msvc@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-win32-ia32-msvc@npm:1.9.1"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@swc/html-win32-x64-msvc@npm:1.9.1":
+ version: 1.9.1
+ resolution: "@swc/html-win32-x64-msvc@npm:1.9.1"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@swc/html@npm:^1.7.39":
+ version: 1.9.1
+ resolution: "@swc/html@npm:1.9.1"
+ dependencies:
+ "@swc/counter": "npm:^0.1.3"
+ "@swc/html-darwin-arm64": "npm:1.9.1"
+ "@swc/html-darwin-x64": "npm:1.9.1"
+ "@swc/html-linux-arm-gnueabihf": "npm:1.9.1"
+ "@swc/html-linux-arm64-gnu": "npm:1.9.1"
+ "@swc/html-linux-arm64-musl": "npm:1.9.1"
+ "@swc/html-linux-x64-gnu": "npm:1.9.1"
+ "@swc/html-linux-x64-musl": "npm:1.9.1"
+ "@swc/html-win32-arm64-msvc": "npm:1.9.1"
+ "@swc/html-win32-ia32-msvc": "npm:1.9.1"
+ "@swc/html-win32-x64-msvc": "npm:1.9.1"
+ dependenciesMeta:
+ "@swc/html-darwin-arm64":
+ optional: true
+ "@swc/html-darwin-x64":
+ optional: true
+ "@swc/html-linux-arm-gnueabihf":
+ optional: true
+ "@swc/html-linux-arm64-gnu":
+ optional: true
+ "@swc/html-linux-arm64-musl":
+ optional: true
+ "@swc/html-linux-x64-gnu":
+ optional: true
+ "@swc/html-linux-x64-musl":
+ optional: true
+ "@swc/html-win32-arm64-msvc":
+ optional: true
+ "@swc/html-win32-ia32-msvc":
+ optional: true
+ "@swc/html-win32-x64-msvc":
+ optional: true
+ checksum: 44c69f1f4cd8b37f315338b2e9ea1c5afa0dd474dcf5a75df6e9a70ed3ed80481c14019307fd00fd104ad4c4c52bbe1e07adf617a478cfb835485ed0fc9f6fd8
+ languageName: node
+ linkType: hard
+
+"@swc/types@npm:^0.1.14":
+ version: 0.1.14
+ resolution: "@swc/types@npm:0.1.14"
+ dependencies:
+ "@swc/counter": "npm:^0.1.3"
+ checksum: 5ab5a213f25fbb038e8b2fa001a20c64363f81c199319373ed0228f316c046a996758fbaf906ba84d297b35e37727082d27974266db320e534da594716626529
languageName: node
linkType: hard
@@ -2909,7 +3210,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/eslint-scope@npm:^3.7.3":
+"@types/eslint-scope@npm:^3.7.7":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
dependencies:
@@ -2938,10 +3239,10 @@ __metadata:
languageName: node
linkType: hard
-"@types/estree@npm:*, @types/estree@npm:^1.0.0":
- version: 1.0.5
- resolution: "@types/estree@npm:1.0.5"
- checksum: b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d
+"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
+ version: 1.0.6
+ resolution: "@types/estree@npm:1.0.6"
+ checksum: cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a
languageName: node
linkType: hard
@@ -3302,154 +3603,154 @@ __metadata:
languageName: node
linkType: hard
-"@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5":
- version: 1.11.6
- resolution: "@webassemblyjs/ast@npm:1.11.6"
+"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.12.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/ast@npm:1.14.1"
dependencies:
- "@webassemblyjs/helper-numbers": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- checksum: e28476a183c8a1787adcf0e5df1d36ec4589467ab712c674fe4f6769c7fb19d1217bfb5856b3edd0f3e0a148ebae9e4bbb84110cee96664966dfef204d9c31fb
+ "@webassemblyjs/helper-numbers": "npm:1.13.2"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ checksum: 67a59be8ed50ddd33fbb2e09daa5193ac215bf7f40a9371be9a0d9797a114d0d1196316d2f3943efdb923a3d809175e1563a3cb80c814fb8edccd1e77494972b
languageName: node
linkType: hard
-"@webassemblyjs/floating-point-hex-parser@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.11.6"
- checksum: 37fe26f89e18e4ca0e7d89cfe3b9f17cfa327d7daf906ae01400416dbb2e33c8a125b4dc55ad7ff405e5fcfb6cf0d764074c9bc532b9a31a71e762be57d2ea0a
+"@webassemblyjs/floating-point-hex-parser@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2"
+ checksum: 0e88bdb8b50507d9938be64df0867f00396b55eba9df7d3546eb5dc0ca64d62e06f8d881ec4a6153f2127d0f4c11d102b6e7d17aec2f26bb5ff95a5e60652412
languageName: node
linkType: hard
-"@webassemblyjs/helper-api-error@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-api-error@npm:1.11.6"
- checksum: a681ed51863e4ff18cf38d223429f414894e5f7496856854d9a886eeddcee32d7c9f66290f2919c9bb6d2fc2b2fae3f989b6a1e02a81e829359738ea0c4d371a
+"@webassemblyjs/helper-api-error@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/helper-api-error@npm:1.13.2"
+ checksum: 31be497f996ed30aae4c08cac3cce50c8dcd5b29660383c0155fce1753804fc55d47fcba74e10141c7dd2899033164e117b3bcfcda23a6b043e4ded4f1003dfb
languageName: node
linkType: hard
-"@webassemblyjs/helper-buffer@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-buffer@npm:1.11.6"
- checksum: 55b5d67db95369cdb2a505ae7ebdf47194d49dfc1aecb0f5403277dcc899c7d3e1f07e8d279646adf8eafd89959272db62ca66fbe803321661ab184176ddfd3a
+"@webassemblyjs/helper-buffer@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/helper-buffer@npm:1.14.1"
+ checksum: 0d54105dc373c0fe6287f1091e41e3a02e36cdc05e8cf8533cdc16c59ff05a646355415893449d3768cda588af451c274f13263300a251dc11a575bc4c9bd210
languageName: node
linkType: hard
-"@webassemblyjs/helper-numbers@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-numbers@npm:1.11.6"
+"@webassemblyjs/helper-numbers@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/helper-numbers@npm:1.13.2"
dependencies:
- "@webassemblyjs/floating-point-hex-parser": "npm:1.11.6"
- "@webassemblyjs/helper-api-error": "npm:1.11.6"
+ "@webassemblyjs/floating-point-hex-parser": "npm:1.13.2"
+ "@webassemblyjs/helper-api-error": "npm:1.13.2"
"@xtuc/long": "npm:4.2.2"
- checksum: c7d5afc0ff3bd748339b466d8d2f27b908208bf3ff26b2e8e72c39814479d486e0dca6f3d4d776fd9027c1efe05b5c0716c57a23041eb34473892b2731c33af3
+ checksum: 9c46852f31b234a8fb5a5a9d3f027bc542392a0d4de32f1a9c0075d5e8684aa073cb5929b56df565500b3f9cc0a2ab983b650314295b9bf208d1a1651bfc825a
languageName: node
linkType: hard
-"@webassemblyjs/helper-wasm-bytecode@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.11.6"
- checksum: 79d2bebdd11383d142745efa32781249745213af8e022651847382685ca76709f83e1d97adc5f0d3c2b8546bf02864f8b43a531fdf5ca0748cb9e4e0ef2acaa5
+"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2"
+ checksum: c4355d14f369b30cf3cbdd3acfafc7d0488e086be6d578e3c9780bd1b512932352246be96e034e2a7fcfba4f540ec813352f312bfcbbfe5bcfbf694f82ccc682
languageName: node
linkType: hard
-"@webassemblyjs/helper-wasm-section@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-wasm-section@npm:1.11.6"
+"@webassemblyjs/helper-wasm-section@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.11.6"
- "@webassemblyjs/helper-buffer": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/wasm-gen": "npm:1.11.6"
- checksum: b79b19a63181f32e5ee0e786fa8264535ea5360276033911fae597d2de15e1776f028091d08c5a813a3901fd2228e74cd8c7e958fded064df734f00546bef8ce
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-buffer": "npm:1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/wasm-gen": "npm:1.14.1"
+ checksum: 1f9b33731c3c6dbac3a9c483269562fa00d1b6a4e7133217f40e83e975e636fd0f8736e53abd9a47b06b66082ecc976c7384391ab0a68e12d509ea4e4b948d64
languageName: node
linkType: hard
-"@webassemblyjs/ieee754@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/ieee754@npm:1.11.6"
+"@webassemblyjs/ieee754@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/ieee754@npm:1.13.2"
dependencies:
"@xtuc/ieee754": "npm:^1.2.0"
- checksum: 59de0365da450322c958deadade5ec2d300c70f75e17ae55de3c9ce564deff5b429e757d107c7ec69bd0ba169c6b6cc2ff66293ab7264a7053c829b50ffa732f
+ checksum: 2e732ca78c6fbae3c9b112f4915d85caecdab285c0b337954b180460290ccd0fb00d2b1dc4bb69df3504abead5191e0d28d0d17dfd6c9d2f30acac8c4961c8a7
languageName: node
linkType: hard
-"@webassemblyjs/leb128@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/leb128@npm:1.11.6"
+"@webassemblyjs/leb128@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/leb128@npm:1.13.2"
dependencies:
"@xtuc/long": "npm:4.2.2"
- checksum: cb344fc04f1968209804de4da018679c5d4708a03b472a33e0fa75657bb024978f570d3ccf9263b7f341f77ecaa75d0e051b9cd4b7bb17a339032cfd1c37f96e
+ checksum: dad5ef9e383c8ab523ce432dfd80098384bf01c45f70eb179d594f85ce5db2f80fa8c9cba03adafd85684e6d6310f0d3969a882538975989919329ac4c984659
languageName: node
linkType: hard
-"@webassemblyjs/utf8@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/utf8@npm:1.11.6"
- checksum: 14d6c24751a89ad9d801180b0d770f30a853c39f035a15fbc96266d6ac46355227abd27a3fd2eeaa97b4294ced2440a6b012750ae17bafe1a7633029a87b6bee
+"@webassemblyjs/utf8@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/utf8@npm:1.13.2"
+ checksum: d3fac9130b0e3e5a1a7f2886124a278e9323827c87a2b971e6d0da22a2ba1278ac9f66a4f2e363ecd9fac8da42e6941b22df061a119e5c0335f81006de9ee799
languageName: node
linkType: hard
-"@webassemblyjs/wasm-edit@npm:^1.11.5":
- version: 1.11.6
- resolution: "@webassemblyjs/wasm-edit@npm:1.11.6"
+"@webassemblyjs/wasm-edit@npm:^1.12.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-edit@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.11.6"
- "@webassemblyjs/helper-buffer": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-section": "npm:1.11.6"
- "@webassemblyjs/wasm-gen": "npm:1.11.6"
- "@webassemblyjs/wasm-opt": "npm:1.11.6"
- "@webassemblyjs/wasm-parser": "npm:1.11.6"
- "@webassemblyjs/wast-printer": "npm:1.11.6"
- checksum: 9a56b6bf635cf7aa5d6e926eaddf44c12fba050170e452a8e17ab4e1b937708678c03f5817120fb9de1e27167667ce693d16ce718d41e5a16393996a6017ab73
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-buffer": "npm:1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/helper-wasm-section": "npm:1.14.1"
+ "@webassemblyjs/wasm-gen": "npm:1.14.1"
+ "@webassemblyjs/wasm-opt": "npm:1.14.1"
+ "@webassemblyjs/wasm-parser": "npm:1.14.1"
+ "@webassemblyjs/wast-printer": "npm:1.14.1"
+ checksum: 5ac4781086a2ca4b320bdbfd965a209655fe8a208ca38d89197148f8597e587c9a2c94fb6bd6f1a7dbd4527c49c6844fcdc2af981f8d793a97bf63a016aa86d2
languageName: node
linkType: hard
-"@webassemblyjs/wasm-gen@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/wasm-gen@npm:1.11.6"
+"@webassemblyjs/wasm-gen@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-gen@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/ieee754": "npm:1.11.6"
- "@webassemblyjs/leb128": "npm:1.11.6"
- "@webassemblyjs/utf8": "npm:1.11.6"
- checksum: ce9a39d3dab2eb4a5df991bc9f3609960daa4671d25d700f4617152f9f79da768547359f817bee10cd88532c3e0a8a1714d383438e0a54217eba53cb822bd5ad
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/ieee754": "npm:1.13.2"
+ "@webassemblyjs/leb128": "npm:1.13.2"
+ "@webassemblyjs/utf8": "npm:1.13.2"
+ checksum: d678810d7f3f8fecb2e2bdadfb9afad2ec1d2bc79f59e4711ab49c81cec578371e22732d4966f59067abe5fba8e9c54923b57060a729d28d408e608beef67b10
languageName: node
linkType: hard
-"@webassemblyjs/wasm-opt@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/wasm-opt@npm:1.11.6"
+"@webassemblyjs/wasm-opt@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-opt@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.11.6"
- "@webassemblyjs/helper-buffer": "npm:1.11.6"
- "@webassemblyjs/wasm-gen": "npm:1.11.6"
- "@webassemblyjs/wasm-parser": "npm:1.11.6"
- checksum: 82788408054171688e9f12883b693777219366d6867003e34dccc21b4a0950ef53edc9d2b4d54cabdb6ee869cf37c8718401b4baa4f70a7f7dd3867c75637298
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-buffer": "npm:1.14.1"
+ "@webassemblyjs/wasm-gen": "npm:1.14.1"
+ "@webassemblyjs/wasm-parser": "npm:1.14.1"
+ checksum: 515bfb15277ee99ba6b11d2232ddbf22aed32aad6d0956fe8a0a0a004a1b5a3a277a71d9a3a38365d0538ac40d1b7b7243b1a244ad6cd6dece1c1bb2eb5de7ee
languageName: node
linkType: hard
-"@webassemblyjs/wasm-parser@npm:1.11.6, @webassemblyjs/wasm-parser@npm:^1.11.5":
- version: 1.11.6
- resolution: "@webassemblyjs/wasm-parser@npm:1.11.6"
+"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.12.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-parser@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.11.6"
- "@webassemblyjs/helper-api-error": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/ieee754": "npm:1.11.6"
- "@webassemblyjs/leb128": "npm:1.11.6"
- "@webassemblyjs/utf8": "npm:1.11.6"
- checksum: 7a97a5f34f98bdcfd812157845a06d53f3d3f67dbd4ae5d6bf66e234e17dc4a76b2b5e74e5dd70b4cab9778fc130194d50bbd6f9a1d23e15ed1ed666233d6f5f
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-api-error": "npm:1.13.2"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/ieee754": "npm:1.13.2"
+ "@webassemblyjs/leb128": "npm:1.13.2"
+ "@webassemblyjs/utf8": "npm:1.13.2"
+ checksum: 95427b9e5addbd0f647939bd28e3e06b8deefdbdadcf892385b5edc70091bf9b92fa5faac3fce8333554437c5d85835afef8c8a7d9d27ab6ba01ffab954db8c6
languageName: node
linkType: hard
-"@webassemblyjs/wast-printer@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/wast-printer@npm:1.11.6"
+"@webassemblyjs/wast-printer@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wast-printer@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.11.6"
+ "@webassemblyjs/ast": "npm:1.14.1"
"@xtuc/long": "npm:4.2.2"
- checksum: 916b90fa3a8aadd95ca41c21d4316d0a7582cf6d0dcf6d9db86ab0de823914df513919fba60ac1edd227ff00e93a66b927b15cbddd36b69d8a34c8815752633c
+ checksum: 8d7768608996a052545251e896eac079c98e0401842af8dd4de78fba8d90bd505efb6c537e909cd6dae96e09db3fa2e765a6f26492553a675da56e2db51f9d24
languageName: node
linkType: hard
@@ -3484,15 +3785,6 @@ __metadata:
languageName: node
linkType: hard
-"acorn-import-assertions@npm:^1.9.0":
- version: 1.9.0
- resolution: "acorn-import-assertions@npm:1.9.0"
- peerDependencies:
- acorn: ^8
- checksum: 3b4a194e128efdc9b86c2b1544f623aba4c1aa70d638f8ab7dc3971a5b4aa4c57bd62f99af6e5325bb5973c55863b4112e708a6f408bad7a138647ca72283afe
- languageName: node
- linkType: hard
-
"acorn-jsx@npm:^5.0.0":
version: 5.3.2
resolution: "acorn-jsx@npm:5.3.2"
@@ -3509,7 +3801,7 @@ __metadata:
languageName: node
linkType: hard
-"acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.7.1, acorn@npm:^8.8.2":
+"acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.8.2":
version: 8.11.2
resolution: "acorn@npm:8.11.2"
bin:
@@ -3518,6 +3810,15 @@ __metadata:
languageName: node
linkType: hard
+"acorn@npm:^8.14.0":
+ version: 8.14.0
+ resolution: "acorn@npm:8.14.0"
+ bin:
+ acorn: bin/acorn
+ checksum: 6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7
+ languageName: node
+ linkType: hard
+
"address@npm:^1.0.1, address@npm:^1.1.2":
version: 1.2.2
resolution: "address@npm:1.2.2"
@@ -3644,6 +3945,15 @@ __metadata:
languageName: node
linkType: hard
+"ansi-escapes@npm:^4.3.2":
+ version: 4.3.2
+ resolution: "ansi-escapes@npm:4.3.2"
+ dependencies:
+ type-fest: "npm:^0.21.3"
+ checksum: da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50
+ languageName: node
+ linkType: hard
+
"ansi-html-community@npm:^0.0.8":
version: 0.0.8
resolution: "ansi-html-community@npm:0.0.8"
@@ -3746,13 +4056,6 @@ __metadata:
languageName: node
linkType: hard
-"asap@npm:~2.0.3":
- version: 2.0.6
- resolution: "asap@npm:2.0.6"
- checksum: c6d5e39fe1f15e4b87677460bd66b66050cd14c772269cee6688824c1410a08ab20254bb6784f9afb75af9144a9f9a7692d49547f4d19d715aeb7c0318f3136d
- languageName: node
- linkType: hard
-
"astring@npm:^1.8.0":
version: 1.8.6
resolution: "astring@npm:1.8.6"
@@ -3762,13 +4065,6 @@ __metadata:
languageName: node
linkType: hard
-"asynckit@npm:^0.4.0":
- version: 0.4.0
- resolution: "asynckit@npm:0.4.0"
- checksum: d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d
- languageName: node
- linkType: hard
-
"at-least-node@npm:^1.0.0":
version: 1.0.0
resolution: "at-least-node@npm:1.0.0"
@@ -3776,45 +4072,34 @@ __metadata:
languageName: node
linkType: hard
-"autoprefixer@npm:^10.4.12, autoprefixer@npm:^10.4.14":
- version: 10.4.16
- resolution: "autoprefixer@npm:10.4.16"
+"autoprefixer@npm:^10.4.14, autoprefixer@npm:^10.4.19":
+ version: 10.4.20
+ resolution: "autoprefixer@npm:10.4.20"
dependencies:
- browserslist: "npm:^4.21.10"
- caniuse-lite: "npm:^1.0.30001538"
- fraction.js: "npm:^4.3.6"
+ browserslist: "npm:^4.23.3"
+ caniuse-lite: "npm:^1.0.30001646"
+ fraction.js: "npm:^4.3.7"
normalize-range: "npm:^0.1.2"
- picocolors: "npm:^1.0.0"
+ picocolors: "npm:^1.0.1"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
postcss: ^8.1.0
bin:
autoprefixer: bin/autoprefixer
- checksum: e00256e754d481a026d928bca729b25954074dd142dbec022f0a7db0d3bbc0dc2e2dc7542e94fec22eff81e21fe140e6856448e2d9a002660cb1e2ad434daee0
- languageName: node
- linkType: hard
-
-"axios@npm:^1.6.1":
- version: 1.6.2
- resolution: "axios@npm:1.6.2"
- dependencies:
- follow-redirects: "npm:^1.15.0"
- form-data: "npm:^4.0.0"
- proxy-from-env: "npm:^1.1.0"
- checksum: 9b77e030e85e4f9cbcba7bb52fbff67d6ce906c92d213e0bd932346a50140faf83733bf786f55bd58301bd92f9973885c7b87d6348023e10f7eaf286d0791a1d
+ checksum: e1f00978a26e7c5b54ab12036d8c13833fad7222828fc90914771b1263f51b28c7ddb5803049de4e77696cbd02bb25cfc3634e80533025bb26c26aacdf938940
languageName: node
linkType: hard
-"babel-loader@npm:^9.1.3":
- version: 9.1.3
- resolution: "babel-loader@npm:9.1.3"
+"babel-loader@npm:^9.2.1":
+ version: 9.2.1
+ resolution: "babel-loader@npm:9.2.1"
dependencies:
find-cache-dir: "npm:^4.0.0"
schema-utils: "npm:^4.0.0"
peerDependencies:
"@babel/core": ^7.12.0
webpack: ">=5"
- checksum: e3fc3c9e02bd908b37e8e8cd4f3d7280cf6ac45e33fc203aedbb615135a0fecc33bf92573b71a166a827af029d302c0b060354985cd91d510320bd70a2f949eb
+ checksum: efb82faff4c7c27e9c15bb28bf11c73200e61cf365118a9514e8d74dd489d0afc2a0d5aaa62cb4254eefc2ab631579224d95a03fd245410f28ea75e24de54ba4
languageName: node
linkType: hard
@@ -3827,39 +4112,39 @@ __metadata:
languageName: node
linkType: hard
-"babel-plugin-polyfill-corejs2@npm:^0.4.6":
- version: 0.4.6
- resolution: "babel-plugin-polyfill-corejs2@npm:0.4.6"
+"babel-plugin-polyfill-corejs2@npm:^0.4.10":
+ version: 0.4.11
+ resolution: "babel-plugin-polyfill-corejs2@npm:0.4.11"
dependencies:
"@babel/compat-data": "npm:^7.22.6"
- "@babel/helper-define-polyfill-provider": "npm:^0.4.3"
+ "@babel/helper-define-polyfill-provider": "npm:^0.6.2"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0
- checksum: 64a98811f343492aa6970ab253760194e389c0417e5b830522f944009c1f0c78e1251975fd1b9869cd48cc4623111b20a3389cf6732a1d10ba0d19de6fa5114f
+ checksum: b2217bc8d5976cf8142453ed44daabf0b2e0e75518f24eac83b54a8892e87a88f1bd9089daa92fd25df979ecd0acfd29b6bc28c4182c1c46344cee15ef9bce84
languageName: node
linkType: hard
-"babel-plugin-polyfill-corejs3@npm:^0.8.5":
- version: 0.8.6
- resolution: "babel-plugin-polyfill-corejs3@npm:0.8.6"
+"babel-plugin-polyfill-corejs3@npm:^0.10.6":
+ version: 0.10.6
+ resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6"
dependencies:
- "@babel/helper-define-polyfill-provider": "npm:^0.4.3"
- core-js-compat: "npm:^3.33.1"
+ "@babel/helper-define-polyfill-provider": "npm:^0.6.2"
+ core-js-compat: "npm:^3.38.0"
peerDependencies:
"@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0
- checksum: 97d974c1dfbefdf27866e21a1ac757f6ab1626379b544d6f8ddb05f7bfa02173f8347b6140295b0f770394549f9321775d3048e466a9a02b99b88ad5f0346858
+ checksum: 3a69220471b07722c2ae6537310bf26b772514e12b601398082965459c838be70a0ca70b0662f0737070654ff6207673391221d48599abb4a2b27765206d9f79
languageName: node
linkType: hard
-"babel-plugin-polyfill-regenerator@npm:^0.5.3":
- version: 0.5.3
- resolution: "babel-plugin-polyfill-regenerator@npm:0.5.3"
+"babel-plugin-polyfill-regenerator@npm:^0.6.1":
+ version: 0.6.2
+ resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2"
dependencies:
- "@babel/helper-define-polyfill-provider": "npm:^0.4.3"
+ "@babel/helper-define-polyfill-provider": "npm:^0.6.2"
peerDependencies:
"@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0
- checksum: cc32313b9ebbf1d7bedc33524a861136b9e5d3b6e9be317ac360a1c2a59ae5ed1b465a6c68b2715cdefb089780ddfb0c11f4a148e49827a947beee76e43da598
+ checksum: bc541037cf7620bc84ddb75a1c0ce3288f90e7d2799c070a53f8a495c8c8ae0316447becb06f958dd25dcce2a2fce855d318ecfa48036a1ddb218d55aa38a744
languageName: node
linkType: hard
@@ -3877,13 +4162,6 @@ __metadata:
languageName: node
linkType: hard
-"base16@npm:^1.0.0":
- version: 1.0.0
- resolution: "base16@npm:1.0.0"
- checksum: af1aee7b297d968528ef47c8de2c5274029743e8a4a5f61ec823e36b673781691d124168cb22936c7997f53d89b344c58bf7ecf93eeb148cffa7e3fb4e4b8b18
- languageName: node
- linkType: hard
-
"batch@npm:0.6.1":
version: 0.6.1
resolution: "batch@npm:0.6.1"
@@ -3995,26 +4273,26 @@ __metadata:
languageName: node
linkType: hard
-"braces@npm:^3.0.2, braces@npm:~3.0.2":
- version: 3.0.2
- resolution: "braces@npm:3.0.2"
+"braces@npm:^3.0.3, braces@npm:~3.0.2":
+ version: 3.0.3
+ resolution: "braces@npm:3.0.3"
dependencies:
- fill-range: "npm:^7.0.1"
- checksum: 321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381
+ fill-range: "npm:^7.1.1"
+ checksum: 7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04
languageName: node
linkType: hard
-"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.21.9, browserslist@npm:^4.22.1":
- version: 4.22.1
- resolution: "browserslist@npm:4.22.1"
+"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.23.0, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0, browserslist@npm:^4.24.2":
+ version: 4.24.2
+ resolution: "browserslist@npm:4.24.2"
dependencies:
- caniuse-lite: "npm:^1.0.30001541"
- electron-to-chromium: "npm:^1.4.535"
- node-releases: "npm:^2.0.13"
- update-browserslist-db: "npm:^1.0.13"
+ caniuse-lite: "npm:^1.0.30001669"
+ electron-to-chromium: "npm:^1.5.41"
+ node-releases: "npm:^2.0.18"
+ update-browserslist-db: "npm:^1.1.1"
bin:
browserslist: cli.js
- checksum: 6810f2d63f171d0b7b8d38cf091708e00cb31525501810a507839607839320d66e657293b0aa3d7f051ecbc025cb07390a90c037682c1d05d12604991e41050b
+ checksum: d747c9fb65ed7b4f1abcae4959405707ed9a7b835639f8a9ba0da2911995a6ab9b0648fd05baf2a4d4e3cf7f9fdbad56d3753f91881e365992c1d49c8d88ff7a
languageName: node
linkType: hard
@@ -4135,10 +4413,17 @@ __metadata:
languageName: node
linkType: hard
-"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001541":
- version: 1.0.30001564
- resolution: "caniuse-lite@npm:1.0.30001564"
- checksum: 27722fea974fc8d2cd334cdef23e1299465c870c97902cc5c293673e6c3ae5241f36f31ca180c903160f0b1c3b51e2b2e8962c537b0a6ac6518a1113b5b5665e
+"caniuse-lite@npm:^1.0.0":
+ version: 1.0.30001677
+ resolution: "caniuse-lite@npm:1.0.30001677"
+ checksum: 22b4aa738b213b5d0bc820c26ba23fa265ca90a5c59776e1a686b9ab6fff9120d0825fd920c0a601a4b65056ef40d01548405feb95c8dd6083255f50c71a0864
+ languageName: node
+ linkType: hard
+
+"caniuse-lite@npm:^1.0.30001616, caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001669":
+ version: 1.0.30001679
+ resolution: "caniuse-lite@npm:1.0.30001679"
+ checksum: 87fb89c5cb5130e40fa97b110fe175ea1104c359e4882aa5e277f824fbd33aa024f26d41a25f7d214db985f43d5b148c44e363965d17b36660b126a03e75e6e0
languageName: node
linkType: hard
@@ -4226,7 +4511,7 @@ __metadata:
languageName: node
linkType: hard
-"cheerio@npm:^1.0.0-rc.12":
+"cheerio@npm:1.0.0-rc.12":
version: 1.0.0-rc.12
resolution: "cheerio@npm:1.0.0-rc.12"
dependencies:
@@ -4328,13 +4613,6 @@ __metadata:
languageName: node
linkType: hard
-"clsx@npm:^1.2.1":
- version: 1.2.1
- resolution: "clsx@npm:1.2.1"
- checksum: 34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27
- languageName: node
- linkType: hard
-
"clsx@npm:^2.0.0":
version: 2.0.0
resolution: "clsx@npm:2.0.0"
@@ -4381,7 +4659,7 @@ __metadata:
languageName: node
linkType: hard
-"colord@npm:^2.9.1":
+"colord@npm:^2.9.3":
version: 2.9.3
resolution: "colord@npm:2.9.3"
checksum: 9699e956894d8996b28c686afe8988720785f476f59335c80ce852ded76ab3ebe252703aec53d9bef54f6219aea6b960fb3d9a8300058a1d0c0d4026460cd110
@@ -4402,15 +4680,6 @@ __metadata:
languageName: node
linkType: hard
-"combined-stream@npm:^1.0.8":
- version: 1.0.8
- resolution: "combined-stream@npm:1.0.8"
- dependencies:
- delayed-stream: "npm:~1.0.0"
- checksum: 0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5
- languageName: node
- linkType: hard
-
"comma-separated-tokens@npm:^2.0.0":
version: 2.0.3
resolution: "comma-separated-tokens@npm:2.0.3"
@@ -4521,10 +4790,10 @@ __metadata:
languageName: node
linkType: hard
-"consola@npm:^2.15.3":
- version: 2.15.3
- resolution: "consola@npm:2.15.3"
- checksum: 34a337e6b4a1349ee4d7b4c568484344418da8fdb829d7d71bfefcd724f608f273987633b6eef465e8de510929907a092e13cb7a28a5d3acb3be446fcc79fd5e
+"consola@npm:^3.2.3":
+ version: 3.2.3
+ resolution: "consola@npm:3.2.3"
+ checksum: c606220524ec88a05bb1baf557e9e0e04a0c08a9c35d7a08652d99de195c4ddcb6572040a7df57a18ff38bbc13ce9880ad032d56630cef27bef72768ef0ac078
languageName: node
linkType: hard
@@ -4595,12 +4864,12 @@ __metadata:
languageName: node
linkType: hard
-"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.33.1":
- version: 3.33.3
- resolution: "core-js-compat@npm:3.33.3"
+"core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1":
+ version: 3.39.0
+ resolution: "core-js-compat@npm:3.39.0"
dependencies:
- browserslist: "npm:^4.22.1"
- checksum: 779997ac791b7f7d01f21312c7b83fff2babb1f632d21fd6cfd8e9c737442475bcb660fade7e1cd7642b5c9593685bc2188089bf86b31d671e8e05e28ee30e58
+ browserslist: "npm:^4.24.2"
+ checksum: 880579a3dab235e3b6350f1e324269c600753b48e891ea859331618d5051e68b7a95db6a03ad2f3cc7df4397318c25a5bc7740562ad39e94f56568638d09d414
languageName: node
linkType: hard
@@ -4638,20 +4907,7 @@ __metadata:
languageName: node
linkType: hard
-"cosmiconfig@npm:^7.0.1":
- version: 7.1.0
- resolution: "cosmiconfig@npm:7.1.0"
- dependencies:
- "@types/parse-json": "npm:^4.0.0"
- import-fresh: "npm:^3.2.1"
- parse-json: "npm:^5.0.0"
- path-type: "npm:^4.0.0"
- yaml: "npm:^1.10.0"
- checksum: b923ff6af581638128e5f074a5450ba12c0300b71302398ea38dbeabd33bbcaa0245ca9adbedfcf284a07da50f99ede5658c80bb3e39e2ce770a99d28a21ef03
- languageName: node
- linkType: hard
-
-"cosmiconfig@npm:^8.2.0":
+"cosmiconfig@npm:^8.1.3, cosmiconfig@npm:^8.2.0":
version: 8.3.6
resolution: "cosmiconfig@npm:8.3.6"
dependencies:
@@ -4668,15 +4924,6 @@ __metadata:
languageName: node
linkType: hard
-"cross-fetch@npm:^3.1.5":
- version: 3.1.8
- resolution: "cross-fetch@npm:3.1.8"
- dependencies:
- node-fetch: "npm:^2.6.12"
- checksum: 4c5e022ffe6abdf380faa6e2373c0c4ed7ef75e105c95c972b6f627c3f083170b6886f19fb488a7fa93971f4f69dcc890f122b0d97f0bf5f41ca1d9a8f58c8af
- languageName: node
- linkType: hard
-
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
@@ -4697,12 +4944,12 @@ __metadata:
languageName: node
linkType: hard
-"css-declaration-sorter@npm:^6.3.1":
- version: 6.4.1
- resolution: "css-declaration-sorter@npm:6.4.1"
+"css-declaration-sorter@npm:^7.2.0":
+ version: 7.2.0
+ resolution: "css-declaration-sorter@npm:7.2.0"
peerDependencies:
postcss: ^8.0.9
- checksum: b8b664338dac528266a1ed9b27927ac51a907fb16bc1954fa9038b5286c442603bd494cc920c6a3616111309d18ee6b5a85b6d9927938efc942af452a5145160
+ checksum: d8516be94f8f2daa233ef021688b965c08161624cbf830a4d7ee1099429437c0ee124d35c91b1c659cfd891a68e8888aa941726dab12279bc114aaed60a94606
languageName: node
linkType: hard
@@ -4724,16 +4971,16 @@ __metadata:
languageName: node
linkType: hard
-"css-minimizer-webpack-plugin@npm:^4.2.2":
- version: 4.2.2
- resolution: "css-minimizer-webpack-plugin@npm:4.2.2"
+"css-minimizer-webpack-plugin@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "css-minimizer-webpack-plugin@npm:5.0.1"
dependencies:
- cssnano: "npm:^5.1.8"
- jest-worker: "npm:^29.1.2"
- postcss: "npm:^8.4.17"
- schema-utils: "npm:^4.0.0"
- serialize-javascript: "npm:^6.0.0"
- source-map: "npm:^0.6.1"
+ "@jridgewell/trace-mapping": "npm:^0.3.18"
+ cssnano: "npm:^6.0.1"
+ jest-worker: "npm:^29.4.3"
+ postcss: "npm:^8.4.24"
+ schema-utils: "npm:^4.0.1"
+ serialize-javascript: "npm:^6.0.1"
peerDependencies:
webpack: ^5.0.0
peerDependenciesMeta:
@@ -4749,7 +4996,7 @@ __metadata:
optional: true
lightningcss:
optional: true
- checksum: 05cd1460b83d9a5f8878fd63d3a80fd100cbb10f48e295a6ad52519761f3390e1e1bc0e269ff28d15b062a1b11379e04608d50ee30424e177c281bd845fef9fb
+ checksum: 1792259e18f7c5ee25b6bbf60b38b64201747add83d1f751c8c654159b46ebacd0d1103d35f17d97197033e21e02d2ba4a4e9aa14c9c0d067b7c7653c721814e
languageName: node
linkType: hard
@@ -4779,13 +5026,23 @@ __metadata:
languageName: node
linkType: hard
-"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3":
- version: 1.1.3
- resolution: "css-tree@npm:1.1.3"
+"css-tree@npm:^2.3.1":
+ version: 2.3.1
+ resolution: "css-tree@npm:2.3.1"
dependencies:
- mdn-data: "npm:2.0.14"
- source-map: "npm:^0.6.1"
- checksum: 499a507bfa39b8b2128f49736882c0dd636b0cd3370f2c69f4558ec86d269113286b7df469afc955de6a68b0dba00bc533e40022a73698081d600072d5d83c1c
+ mdn-data: "npm:2.0.30"
+ source-map-js: "npm:^1.0.1"
+ checksum: 6f8c1a11d5e9b14bf02d10717fc0351b66ba12594166f65abfbd8eb8b5b490dd367f5c7721db241a3c792d935fc6751fbc09f7e1598d421477ad9fadc30f4f24
+ languageName: node
+ linkType: hard
+
+"css-tree@npm:~2.2.0":
+ version: 2.2.1
+ resolution: "css-tree@npm:2.2.1"
+ dependencies:
+ mdn-data: "npm:2.0.28"
+ source-map-js: "npm:^1.0.1"
+ checksum: 47e87b0f02f8ac22f57eceb65c58011dd142d2158128882a0bf963cf2eabb81a4ebbc2e3790c8289be7919fa8b83750c7b69272bd66772c708143b772ba3c186
languageName: node
linkType: hard
@@ -4805,89 +5062,90 @@ __metadata:
languageName: node
linkType: hard
-"cssnano-preset-advanced@npm:^5.3.10":
- version: 5.3.10
- resolution: "cssnano-preset-advanced@npm:5.3.10"
- dependencies:
- autoprefixer: "npm:^10.4.12"
- cssnano-preset-default: "npm:^5.2.14"
- postcss-discard-unused: "npm:^5.1.0"
- postcss-merge-idents: "npm:^5.1.1"
- postcss-reduce-idents: "npm:^5.2.0"
- postcss-zindex: "npm:^5.1.0"
- peerDependencies:
- postcss: ^8.2.15
- checksum: abfa870a6e3ab52cddfea7cac83f49b510efb941c7f2960ca9d41ae11fabbe03e9453cad7f81fd1b35cf6080c94094cd7bb1b58c07fad4cf0453f6e4bb9a07ae
- languageName: node
- linkType: hard
-
-"cssnano-preset-default@npm:^5.2.14":
- version: 5.2.14
- resolution: "cssnano-preset-default@npm:5.2.14"
- dependencies:
- css-declaration-sorter: "npm:^6.3.1"
- cssnano-utils: "npm:^3.1.0"
- postcss-calc: "npm:^8.2.3"
- postcss-colormin: "npm:^5.3.1"
- postcss-convert-values: "npm:^5.1.3"
- postcss-discard-comments: "npm:^5.1.2"
- postcss-discard-duplicates: "npm:^5.1.0"
- postcss-discard-empty: "npm:^5.1.1"
- postcss-discard-overridden: "npm:^5.1.0"
- postcss-merge-longhand: "npm:^5.1.7"
- postcss-merge-rules: "npm:^5.1.4"
- postcss-minify-font-values: "npm:^5.1.0"
- postcss-minify-gradients: "npm:^5.1.1"
- postcss-minify-params: "npm:^5.1.4"
- postcss-minify-selectors: "npm:^5.2.1"
- postcss-normalize-charset: "npm:^5.1.0"
- postcss-normalize-display-values: "npm:^5.1.0"
- postcss-normalize-positions: "npm:^5.1.1"
- postcss-normalize-repeat-style: "npm:^5.1.1"
- postcss-normalize-string: "npm:^5.1.0"
- postcss-normalize-timing-functions: "npm:^5.1.0"
- postcss-normalize-unicode: "npm:^5.1.1"
- postcss-normalize-url: "npm:^5.1.0"
- postcss-normalize-whitespace: "npm:^5.1.1"
- postcss-ordered-values: "npm:^5.1.3"
- postcss-reduce-initial: "npm:^5.1.2"
- postcss-reduce-transforms: "npm:^5.1.0"
- postcss-svgo: "npm:^5.1.0"
- postcss-unique-selectors: "npm:^5.1.1"
- peerDependencies:
- postcss: ^8.2.15
- checksum: d125bdb9ac007f97f920e30be953c550a8e7de0cb9298f67e0bc9744f4b920039046b5a6b817e345872836b08689af747f82fbf2189c8bd48da3e6f0c1087b89
- languageName: node
- linkType: hard
-
-"cssnano-utils@npm:^3.1.0":
- version: 3.1.0
- resolution: "cssnano-utils@npm:3.1.0"
+"cssnano-preset-advanced@npm:^6.1.2":
+ version: 6.1.2
+ resolution: "cssnano-preset-advanced@npm:6.1.2"
+ dependencies:
+ autoprefixer: "npm:^10.4.19"
+ browserslist: "npm:^4.23.0"
+ cssnano-preset-default: "npm:^6.1.2"
+ postcss-discard-unused: "npm:^6.0.5"
+ postcss-merge-idents: "npm:^6.0.3"
+ postcss-reduce-idents: "npm:^6.0.3"
+ postcss-zindex: "npm:^6.0.2"
+ peerDependencies:
+ postcss: ^8.4.31
+ checksum: 22d3ddab258e6b31e7e2e7c48712f023b60fadb2813929752dace0326e28cd250830b5420a33f81b01df52d2460cb5f999fff5907f58508809efe1a8a739a707
+ languageName: node
+ linkType: hard
+
+"cssnano-preset-default@npm:^6.1.2":
+ version: 6.1.2
+ resolution: "cssnano-preset-default@npm:6.1.2"
+ dependencies:
+ browserslist: "npm:^4.23.0"
+ css-declaration-sorter: "npm:^7.2.0"
+ cssnano-utils: "npm:^4.0.2"
+ postcss-calc: "npm:^9.0.1"
+ postcss-colormin: "npm:^6.1.0"
+ postcss-convert-values: "npm:^6.1.0"
+ postcss-discard-comments: "npm:^6.0.2"
+ postcss-discard-duplicates: "npm:^6.0.3"
+ postcss-discard-empty: "npm:^6.0.3"
+ postcss-discard-overridden: "npm:^6.0.2"
+ postcss-merge-longhand: "npm:^6.0.5"
+ postcss-merge-rules: "npm:^6.1.1"
+ postcss-minify-font-values: "npm:^6.1.0"
+ postcss-minify-gradients: "npm:^6.0.3"
+ postcss-minify-params: "npm:^6.1.0"
+ postcss-minify-selectors: "npm:^6.0.4"
+ postcss-normalize-charset: "npm:^6.0.2"
+ postcss-normalize-display-values: "npm:^6.0.2"
+ postcss-normalize-positions: "npm:^6.0.2"
+ postcss-normalize-repeat-style: "npm:^6.0.2"
+ postcss-normalize-string: "npm:^6.0.2"
+ postcss-normalize-timing-functions: "npm:^6.0.2"
+ postcss-normalize-unicode: "npm:^6.1.0"
+ postcss-normalize-url: "npm:^6.0.2"
+ postcss-normalize-whitespace: "npm:^6.0.2"
+ postcss-ordered-values: "npm:^6.0.2"
+ postcss-reduce-initial: "npm:^6.1.0"
+ postcss-reduce-transforms: "npm:^6.0.2"
+ postcss-svgo: "npm:^6.0.3"
+ postcss-unique-selectors: "npm:^6.0.4"
+ peerDependencies:
+ postcss: ^8.4.31
+ checksum: af99021f936763850f5f35dc9e6a9dfb0da30856dea36e0420b011da2a447099471db2a5f3d1f5f52c0489da186caf9a439d8f048a80f82617077efb018333fa
+ languageName: node
+ linkType: hard
+
+"cssnano-utils@npm:^4.0.2":
+ version: 4.0.2
+ resolution: "cssnano-utils@npm:4.0.2"
peerDependencies:
- postcss: ^8.2.15
- checksum: 057508645a3e7584decede1045daa5b362dbfa2f5df96c3527c7d52e41e787a3442a56a8ea0c0af6a757f518e79a459ee580a35c323ad0d0eec912afd67d7630
+ postcss: ^8.4.31
+ checksum: 260b8c8ffa48b908aa77ef129f9b8648ecd92aed405b20e7fe6b8370779dd603530344fc9d96683d53533246e48b36ac9d2aa5a476b4f81c547bbad86d187f35
languageName: node
linkType: hard
-"cssnano@npm:^5.1.15, cssnano@npm:^5.1.8":
- version: 5.1.15
- resolution: "cssnano@npm:5.1.15"
+"cssnano@npm:^6.0.1, cssnano@npm:^6.1.2":
+ version: 6.1.2
+ resolution: "cssnano@npm:6.1.2"
dependencies:
- cssnano-preset-default: "npm:^5.2.14"
- lilconfig: "npm:^2.0.3"
- yaml: "npm:^1.10.2"
+ cssnano-preset-default: "npm:^6.1.2"
+ lilconfig: "npm:^3.1.1"
peerDependencies:
- postcss: ^8.2.15
- checksum: 4252e4f4edd7a0fbdd4017825c0f8632b7a12ecbfdd432d2ff7ec268d48eb956a0a10bbf209602181f9f84ceeecea4a864719ecde03aa2cc48f5d9636fcf5f9a
+ postcss: ^8.4.31
+ checksum: 4df0dc0389b34b38acb09b7cfb07267b0eda95349c6d5e9b7666acc7200bb33359650869a60168e9d878298b05f4ad2c7f070815c90551720a3f4e1037f79691
languageName: node
linkType: hard
-"csso@npm:^4.2.0":
- version: 4.2.0
- resolution: "csso@npm:4.2.0"
+"csso@npm:^5.0.5":
+ version: 5.0.5
+ resolution: "csso@npm:5.0.5"
dependencies:
- css-tree: "npm:^1.1.2"
- checksum: f8c6b1300efaa0f8855a7905ae3794a29c6496e7f16a71dec31eb6ca7cfb1f058a4b03fd39b66c4deac6cb06bf6b4ba86da7b67d7320389cb9994d52b924b903
+ css-tree: "npm:~2.2.0"
+ checksum: ab4beb1e97dd7e207c10e9925405b45f15a6cd1b4880a8686ad573aa6d476aed28b4121a666cffd26c37a26179f7b54741f7c257543003bfb244d06a62ad569b
languageName: node
linkType: hard
@@ -4926,6 +5184,18 @@ __metadata:
languageName: node
linkType: hard
+"debug@npm:^4.3.1":
+ version: 4.3.7
+ resolution: "debug@npm:4.3.7"
+ dependencies:
+ ms: "npm:^2.1.3"
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ checksum: 1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b
+ languageName: node
+ linkType: hard
+
"decode-named-character-reference@npm:^1.0.0":
version: 1.0.2
resolution: "decode-named-character-reference@npm:1.0.2"
@@ -4958,7 +5228,7 @@ __metadata:
languageName: node
linkType: hard
-"deepmerge@npm:^4.2.2":
+"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.1":
version: 4.3.1
resolution: "deepmerge@npm:4.3.1"
checksum: e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044
@@ -5026,13 +5296,6 @@ __metadata:
languageName: node
linkType: hard
-"delayed-stream@npm:~1.0.0":
- version: 1.0.0
- resolution: "delayed-stream@npm:1.0.0"
- checksum: d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19
- languageName: node
- linkType: hard
-
"depd@npm:2.0.0":
version: 2.0.0
resolution: "depd@npm:2.0.0"
@@ -5068,6 +5331,15 @@ __metadata:
languageName: node
linkType: hard
+"detect-libc@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "detect-libc@npm:1.0.3"
+ bin:
+ detect-libc: ./bin/detect-libc.js
+ checksum: 4da0deae9f69e13bc37a0902d78bf7169480004b1fed3c19722d56cff578d16f0e11633b7fbf5fb6249181236c72e90024cbd68f0b9558ae06e281f47326d50d
+ languageName: node
+ linkType: hard
+
"detect-node@npm:^2.0.4":
version: 2.1.0
resolution: "detect-node@npm:2.1.0"
@@ -5253,10 +5525,10 @@ __metadata:
languageName: node
linkType: hard
-"electron-to-chromium@npm:^1.4.535":
- version: 1.4.590
- resolution: "electron-to-chromium@npm:1.4.590"
- checksum: 2277824b96fb6f37856ae809de1ad9ee9a9e31ffda39aa16c99a126ea5bdb2e4c89521ea3c529dc970cb50827ec3535b7637c4a2767abc473bb0b95ed1f46c7e
+"electron-to-chromium@npm:^1.5.41":
+ version: 1.5.55
+ resolution: "electron-to-chromium@npm:1.5.55"
+ checksum: 1b9e0970a591d342cf4d4c95b63bcdb8bffed01edb7c8baed8dd54ea769c8b33c07484c94a031a20363a8129ca2ad1d612ce4ca55ec831244240ae1e6bcdf07c
languageName: node
linkType: hard
@@ -5311,13 +5583,13 @@ __metadata:
languageName: node
linkType: hard
-"enhanced-resolve@npm:^5.15.0":
- version: 5.15.0
- resolution: "enhanced-resolve@npm:5.15.0"
+"enhanced-resolve@npm:^5.17.1":
+ version: 5.17.1
+ resolution: "enhanced-resolve@npm:5.17.1"
dependencies:
graceful-fs: "npm:^4.2.4"
tapable: "npm:^2.2.0"
- checksum: 69984a7990913948b4150855aed26a84afb4cb1c5a94fb8e3a65bd00729a73fc2eaff6871fb8e345377f294831afe349615c93560f2f54d61b43cdfdf668f19a
+ checksum: 81a0515675eca17efdba2cf5bad87abc91a528fc1191aad50e275e74f045b41506167d420099022da7181c8d787170ea41e4a11a0b10b7a16f6237daecb15370
languageName: node
linkType: hard
@@ -5335,13 +5607,6 @@ __metadata:
languageName: node
linkType: hard
-"entities@npm:~3.0.1":
- version: 3.0.1
- resolution: "entities@npm:3.0.1"
- checksum: 2d93f48fd86de0b0ed8ee34456aa47b4e74a916a5e663cfcc7048302e2c7e932002926daf5a00ad6d5691e3c90673a15d413704d86d7e1b9532f9bc00d975590
- languageName: node
- linkType: hard
-
"env-paths@npm:^2.2.0":
version: 2.2.1
resolution: "env-paths@npm:2.2.1"
@@ -5372,10 +5637,10 @@ __metadata:
languageName: node
linkType: hard
-"escalade@npm:^3.1.1":
- version: 3.1.1
- resolution: "escalade@npm:3.1.1"
- checksum: afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d
+"escalade@npm:^3.1.1, escalade@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "escalade@npm:3.2.0"
+ checksum: ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65
languageName: node
linkType: hard
@@ -5676,15 +5941,6 @@ __metadata:
languageName: node
linkType: hard
-"fast-url-parser@npm:1.1.3":
- version: 1.1.3
- resolution: "fast-url-parser@npm:1.1.3"
- dependencies:
- punycode: "npm:^1.3.2"
- checksum: d85c5c409cf0215417380f98a2d29c23a95004d93ff0d8bdf1af5f1a9d1fc608ac89ac6ffe863783d2c73efb3850dd35390feb1de3296f49877bfee0392eb5d3
- languageName: node
- linkType: hard
-
"fastq@npm:^1.6.0":
version: 1.15.0
resolution: "fastq@npm:1.15.0"
@@ -5712,37 +5968,6 @@ __metadata:
languageName: node
linkType: hard
-"fbemitter@npm:^3.0.0":
- version: 3.0.0
- resolution: "fbemitter@npm:3.0.0"
- dependencies:
- fbjs: "npm:^3.0.0"
- checksum: f130dd8e15dc3fc6709a26586b7a589cd994e1d1024b624f2cc8ef1b12401536a94bb30038e68150a24f9ba18863e9a3fe87941ade2c87667bfbd17f4848d5c7
- languageName: node
- linkType: hard
-
-"fbjs-css-vars@npm:^1.0.0":
- version: 1.0.2
- resolution: "fbjs-css-vars@npm:1.0.2"
- checksum: dfb64116b125a64abecca9e31477b5edb9a2332c5ffe74326fe36e0a72eef7fc8a49b86adf36c2c293078d79f4524f35e80f5e62546395f53fb7c9e69821f54f
- languageName: node
- linkType: hard
-
-"fbjs@npm:^3.0.0, fbjs@npm:^3.0.1":
- version: 3.0.5
- resolution: "fbjs@npm:3.0.5"
- dependencies:
- cross-fetch: "npm:^3.1.5"
- fbjs-css-vars: "npm:^1.0.0"
- loose-envify: "npm:^1.0.0"
- object-assign: "npm:^4.1.0"
- promise: "npm:^7.1.1"
- setimmediate: "npm:^1.0.5"
- ua-parser-js: "npm:^1.0.35"
- checksum: 66d0a2fc9a774f9066e35ac2ac4bf1245931d27f3ac287c7d47e6aa1fc152b243c2109743eb8f65341e025621fb51a12038fadb9fd8fda2e3ddae04ebab06f91
- languageName: node
- linkType: hard
-
"feed@npm:^4.2.2":
version: 4.2.2
resolution: "feed@npm:4.2.2"
@@ -5752,6 +5977,15 @@ __metadata:
languageName: node
linkType: hard
+"figures@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "figures@npm:3.2.0"
+ dependencies:
+ escape-string-regexp: "npm:^1.0.5"
+ checksum: 9c421646ede432829a50bc4e55c7a4eb4bcb7cc07b5bab2f471ef1ab9a344595bbebb6c5c21470093fbb730cd81bbca119624c40473a125293f656f49cb47629
+ languageName: node
+ linkType: hard
+
"file-loader@npm:^6.2.0":
version: 6.2.0
resolution: "file-loader@npm:6.2.0"
@@ -5771,12 +6005,12 @@ __metadata:
languageName: node
linkType: hard
-"fill-range@npm:^7.0.1":
- version: 7.0.1
- resolution: "fill-range@npm:7.0.1"
+"fill-range@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "fill-range@npm:7.1.1"
dependencies:
to-regex-range: "npm:^5.0.1"
- checksum: 7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f
+ checksum: b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
languageName: node
linkType: hard
@@ -5850,19 +6084,7 @@ __metadata:
languageName: node
linkType: hard
-"flux@npm:~4.0.1":
- version: 4.0.4
- resolution: "flux@npm:4.0.4"
- dependencies:
- fbemitter: "npm:^3.0.0"
- fbjs: "npm:^3.0.1"
- peerDependencies:
- react: ^15.0.2 || ^16.0.0 || ^17.0.0
- checksum: 948bc01b97ff21babc8bfe5c40543d643ca126b71edd447a9ac051b05d20fd549a6bcc4afe043bcde56201782e688a5eaeda1bd8e3e58915641abdd5b3ea21e0
- languageName: node
- linkType: hard
-
-"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0":
+"follow-redirects@npm:^1.0.0":
version: 1.15.3
resolution: "follow-redirects@npm:1.15.3"
peerDependenciesMeta:
@@ -5920,17 +6142,6 @@ __metadata:
languageName: node
linkType: hard
-"form-data@npm:^4.0.0":
- version: 4.0.0
- resolution: "form-data@npm:4.0.0"
- dependencies:
- asynckit: "npm:^0.4.0"
- combined-stream: "npm:^1.0.8"
- mime-types: "npm:^2.1.12"
- checksum: cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e
- languageName: node
- linkType: hard
-
"format@npm:^0.2.0":
version: 0.2.2
resolution: "format@npm:0.2.2"
@@ -5945,7 +6156,7 @@ __metadata:
languageName: node
linkType: hard
-"fraction.js@npm:^4.3.6":
+"fraction.js@npm:^4.3.7":
version: 4.3.7
resolution: "fraction.js@npm:4.3.7"
checksum: df291391beea9ab4c263487ffd9d17fed162dbb736982dee1379b2a8cc94e4e24e46ed508c6d278aded9080ba51872f1bc5f3a5fd8d7c74e5f105b508ac28711
@@ -5959,14 +6170,14 @@ __metadata:
languageName: node
linkType: hard
-"fs-extra@npm:^11.1.1":
- version: 11.1.1
- resolution: "fs-extra@npm:11.1.1"
+"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0":
+ version: 11.2.0
+ resolution: "fs-extra@npm:11.2.0"
dependencies:
graceful-fs: "npm:^4.2.0"
jsonfile: "npm:^6.0.1"
universalify: "npm:^2.0.0"
- checksum: a2480243d7dcfa7d723c5f5b24cf4eba02a6ccece208f1524a2fbde1c629492cfb9a59e4b6d04faff6fbdf71db9fdc8ef7f396417a02884195a625f5d8dc9427
+ checksum: d77a9a9efe60532d2e790e938c81a02c1b24904ef7a3efb3990b835514465ba720e99a6ea56fd5e2db53b4695319b644d76d5a0e9988a2beef80aa7b1da63398
languageName: node
linkType: hard
@@ -6170,17 +6381,17 @@ __metadata:
languageName: node
linkType: hard
-"globby@npm:14.0.0":
- version: 14.0.0
- resolution: "globby@npm:14.0.0"
+"globby@npm:14.0.2":
+ version: 14.0.2
+ resolution: "globby@npm:14.0.2"
dependencies:
- "@sindresorhus/merge-streams": "npm:^1.0.0"
+ "@sindresorhus/merge-streams": "npm:^2.1.0"
fast-glob: "npm:^3.3.2"
ignore: "npm:^5.2.4"
path-type: "npm:^5.0.0"
slash: "npm:^5.1.0"
unicorn-magic: "npm:^0.1.0"
- checksum: 6d98738a419f948ef23da019275b15ca5c65bb7e354ecea52a3015f4dae6b28a713fcf73bf3aab1c04039f4f62da71cff191a7ececc37c0e4c9b4320a047505f
+ checksum: 3f771cd683b8794db1e7ebc8b6b888d43496d93a82aad4e9d974620f578581210b6c5a6e75ea29573ed16a1345222fab6e9b877a8d1ed56eeb147e09f69c6f78
languageName: node
linkType: hard
@@ -6246,7 +6457,7 @@ __metadata:
languageName: node
linkType: hard
-"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
+"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
version: 4.2.11
resolution: "graceful-fs@npm:4.2.11"
checksum: 386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
@@ -6564,9 +6775,9 @@ __metadata:
languageName: node
linkType: hard
-"html-webpack-plugin@npm:^5.5.3":
- version: 5.5.3
- resolution: "html-webpack-plugin@npm:5.5.3"
+"html-webpack-plugin@npm:^5.6.0":
+ version: 5.6.3
+ resolution: "html-webpack-plugin@npm:5.6.3"
dependencies:
"@types/html-minifier-terser": "npm:^6.0.0"
html-minifier-terser: "npm:^6.0.2"
@@ -6574,8 +6785,14 @@ __metadata:
pretty-error: "npm:^4.0.0"
tapable: "npm:^2.0.0"
peerDependencies:
+ "@rspack/core": 0.x || 1.x
webpack: ^5.20.0
- checksum: 7ba0d0f87d08f5c4c51f821842d736ec1762940bc39798932528adaec1e9cca8f52944987b88789007f5706d15110edbdfa30df445d61c6628b02ebe163c4f42
+ peerDependenciesMeta:
+ "@rspack/core":
+ optional: true
+ webpack:
+ optional: true
+ checksum: 25a21f83a8823d3711396dd8050bc0080c0ae55537352d432903eff58a7d9838fc811e3c26462419036190720357e67c7977efd106fb9a252770632824f0cc25
languageName: node
linkType: hard
@@ -6767,7 +6984,7 @@ __metadata:
languageName: node
linkType: hard
-"import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0":
+"import-fresh@npm:^3.1.0, import-fresh@npm:^3.3.0":
version: 3.3.0
resolution: "import-fresh@npm:3.3.0"
dependencies:
@@ -6798,10 +7015,10 @@ __metadata:
languageName: node
linkType: hard
-"infima@npm:0.2.0-alpha.43":
- version: 0.2.0-alpha.43
- resolution: "infima@npm:0.2.0-alpha.43"
- checksum: d248958713a97e1c9f73ace27ceff726ba86a9b534efb0ebdec3e72b785d8edb36db922e38ce09bbeb98a17b657e61357f22edc3a58f02ad51b7ae2ebd96e4e4
+"infima@npm:0.2.0-alpha.45":
+ version: 0.2.0-alpha.45
+ resolution: "infima@npm:0.2.0-alpha.45"
+ checksum: b50d103f6864687742067414d09392ccf3be363cf27503925a943ff56bb2392118e2bfdb6b2f89933417015e1770e58f81b2b0caf823f2adfb67f32b1702d469
languageName: node
linkType: hard
@@ -7075,13 +7292,6 @@ __metadata:
languageName: node
linkType: hard
-"is-plain-object@npm:^5.0.0":
- version: 5.0.0
- resolution: "is-plain-object@npm:5.0.0"
- checksum: 893e42bad832aae3511c71fd61c0bf61aa3a6d853061c62a307261842727d0d25f761ce9379f7ba7226d6179db2a3157efa918e7fe26360f3bf0842d9f28942c
- languageName: node
- linkType: hard
-
"is-reference@npm:^3.0.0":
version: 3.0.2
resolution: "is-reference@npm:3.0.2"
@@ -7208,7 +7418,7 @@ __metadata:
languageName: node
linkType: hard
-"jest-worker@npm:^29.1.2":
+"jest-worker@npm:^29.4.3":
version: 29.7.0
resolution: "jest-worker@npm:29.7.0"
dependencies:
@@ -7229,7 +7439,7 @@ __metadata:
languageName: node
linkType: hard
-"joi@npm:^17.11.0, joi@npm:^17.9.2":
+"joi@npm:^17.9.2":
version: 17.11.0
resolution: "joi@npm:17.11.0"
dependencies:
@@ -7249,19 +7459,7 @@ __metadata:
languageName: node
linkType: hard
-"js-yaml@npm:^3.13.1":
- version: 3.14.1
- resolution: "js-yaml@npm:3.14.1"
- dependencies:
- argparse: "npm:^1.0.7"
- esprima: "npm:^4.0.0"
- bin:
- js-yaml: bin/js-yaml.js
- checksum: 6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b
- languageName: node
- linkType: hard
-
-"js-yaml@npm:^4.1.0":
+"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0":
version: 4.1.0
resolution: "js-yaml@npm:4.1.0"
dependencies:
@@ -7272,21 +7470,24 @@ __metadata:
languageName: node
linkType: hard
-"jsesc@npm:^2.5.1":
- version: 2.5.2
- resolution: "jsesc@npm:2.5.2"
+"js-yaml@npm:^3.13.1":
+ version: 3.14.1
+ resolution: "js-yaml@npm:3.14.1"
+ dependencies:
+ argparse: "npm:^1.0.7"
+ esprima: "npm:^4.0.0"
bin:
- jsesc: bin/jsesc
- checksum: dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88
+ js-yaml: bin/js-yaml.js
+ checksum: 6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b
languageName: node
linkType: hard
-"jsesc@npm:~0.5.0":
- version: 0.5.0
- resolution: "jsesc@npm:0.5.0"
+"jsesc@npm:^3.0.2, jsesc@npm:~3.0.2":
+ version: 3.0.2
+ resolution: "jsesc@npm:3.0.2"
bin:
jsesc: bin/jsesc
- checksum: f93792440ae1d80f091b65f8ceddf8e55c4bb7f1a09dee5dcbdb0db5612c55c0f6045625aa6b7e8edb2e0a4feabd80ee48616dbe2d37055573a84db3d24f96d9
+ checksum: ef22148f9e793180b14d8a145ee6f9f60f301abf443288117b4b6c53d0ecd58354898dc506ccbb553a5f7827965cd38bc5fb726575aae93c5e8915e2de8290e1
languageName: node
linkType: hard
@@ -7327,6 +7528,13 @@ __metadata:
languageName: node
linkType: hard
+"jsonc-parser@npm:3.3.1":
+ version: 3.3.1
+ resolution: "jsonc-parser@npm:3.3.1"
+ checksum: 269c3ae0a0e4f907a914bf334306c384aabb9929bd8c99f909275ebd5c2d3bc70b9bcd119ad794f339dec9f24b6a4ee9cd5a8ab2e6435e730ad4075388fc2ab6
+ languageName: node
+ linkType: hard
+
"jsonfile@npm:^6.0.1":
version: 6.1.0
resolution: "jsonfile@npm:6.1.0"
@@ -7389,10 +7597,120 @@ __metadata:
languageName: node
linkType: hard
-"lilconfig@npm:^2.0.3":
- version: 2.1.0
- resolution: "lilconfig@npm:2.1.0"
- checksum: 64645641aa8d274c99338e130554abd6a0190533c0d9eb2ce7ebfaf2e05c7d9961f3ffe2bfa39efd3b60c521ba3dd24fa236fe2775fc38501bf82bf49d4678b8
+"lightningcss-darwin-arm64@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-darwin-arm64@npm:1.28.1"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"lightningcss-darwin-x64@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-darwin-x64@npm:1.28.1"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"lightningcss-freebsd-x64@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-freebsd-x64@npm:1.28.1"
+ conditions: os=freebsd & cpu=x64
+ languageName: node
+ linkType: hard
+
+"lightningcss-linux-arm-gnueabihf@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-linux-arm-gnueabihf@npm:1.28.1"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
+"lightningcss-linux-arm64-gnu@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-linux-arm64-gnu@npm:1.28.1"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"lightningcss-linux-arm64-musl@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-linux-arm64-musl@npm:1.28.1"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"lightningcss-linux-x64-gnu@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-linux-x64-gnu@npm:1.28.1"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"lightningcss-linux-x64-musl@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-linux-x64-musl@npm:1.28.1"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"lightningcss-win32-arm64-msvc@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-win32-arm64-msvc@npm:1.28.1"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"lightningcss-win32-x64-msvc@npm:1.28.1":
+ version: 1.28.1
+ resolution: "lightningcss-win32-x64-msvc@npm:1.28.1"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"lightningcss@npm:^1.27.0":
+ version: 1.28.1
+ resolution: "lightningcss@npm:1.28.1"
+ dependencies:
+ detect-libc: "npm:^1.0.3"
+ lightningcss-darwin-arm64: "npm:1.28.1"
+ lightningcss-darwin-x64: "npm:1.28.1"
+ lightningcss-freebsd-x64: "npm:1.28.1"
+ lightningcss-linux-arm-gnueabihf: "npm:1.28.1"
+ lightningcss-linux-arm64-gnu: "npm:1.28.1"
+ lightningcss-linux-arm64-musl: "npm:1.28.1"
+ lightningcss-linux-x64-gnu: "npm:1.28.1"
+ lightningcss-linux-x64-musl: "npm:1.28.1"
+ lightningcss-win32-arm64-msvc: "npm:1.28.1"
+ lightningcss-win32-x64-msvc: "npm:1.28.1"
+ dependenciesMeta:
+ lightningcss-darwin-arm64:
+ optional: true
+ lightningcss-darwin-x64:
+ optional: true
+ lightningcss-freebsd-x64:
+ optional: true
+ lightningcss-linux-arm-gnueabihf:
+ optional: true
+ lightningcss-linux-arm64-gnu:
+ optional: true
+ lightningcss-linux-arm64-musl:
+ optional: true
+ lightningcss-linux-x64-gnu:
+ optional: true
+ lightningcss-linux-x64-musl:
+ optional: true
+ lightningcss-win32-arm64-msvc:
+ optional: true
+ lightningcss-win32-x64-msvc:
+ optional: true
+ checksum: 8bd23ca3dc3d701e89490b88a59470d27887ff7703e9e27c8a7f04d9cd35ca9c7e88390fbcb82fe179c20c912538c0d028f12a4f26a556f00567274804699691
+ languageName: node
+ linkType: hard
+
+"lilconfig@npm:^3.1.1":
+ version: 3.1.2
+ resolution: "lilconfig@npm:3.1.2"
+ checksum: f059630b1a9bddaeba83059db00c672b64dc14074e9f232adce32b38ca1b5686ab737eb665c5ba3c32f147f0002b4bee7311ad0386a9b98547b5623e87071fbe
languageName: node
linkType: hard
@@ -7403,12 +7721,12 @@ __metadata:
languageName: node
linkType: hard
-"linkify-it@npm:^4.0.1":
- version: 4.0.1
- resolution: "linkify-it@npm:4.0.1"
+"linkify-it@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "linkify-it@npm:5.0.0"
dependencies:
- uc.micro: "npm:^1.0.1"
- checksum: f1949ee2c7c2979c4f80c8c08f507d813f50775ebc5adfdb7ee662f28e0ee53dbd4a329d5231be67414405fc60d4e99b37536d6949702d311fe509a6bcbcf4a6
+ uc.micro: "npm:^2.0.0"
+ checksum: ff4abbcdfa2003472fc3eb4b8e60905ec97718e11e33cca52059919a4c80cc0e0c2a14d23e23d8c00e5402bc5a885cdba8ca053a11483ab3cc8b3c7a52f88e2d
languageName: node
linkType: hard
@@ -7465,13 +7783,6 @@ __metadata:
languageName: node
linkType: hard
-"lodash.curry@npm:^4.0.1":
- version: 4.1.1
- resolution: "lodash.curry@npm:4.1.1"
- checksum: f0431947dc9236df879fc13eb40c31a2839c958bd0eaa39170a5758c25a7d85d461716a851ab45a175371950b283480615cdd4b07fb0dd1afff7a2914a90696f
- languageName: node
- linkType: hard
-
"lodash.debounce@npm:^4.0.8":
version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8"
@@ -7479,13 +7790,6 @@ __metadata:
languageName: node
linkType: hard
-"lodash.flow@npm:^3.3.0":
- version: 3.5.0
- resolution: "lodash.flow@npm:3.5.0"
- checksum: b3202ddbb79e5aab41719806d0d5ae969f64ae6b59e6bdaaecaa96ec68d6ba429e544017fe0e71ecf5b7ee3cea7b45d43c46b7d67ca159d6cca86fca76c61a31
- languageName: node
- linkType: hard
-
"lodash.memoize@npm:^4.1.2":
version: 4.1.2
resolution: "lodash.memoize@npm:4.1.2"
@@ -7592,18 +7896,28 @@ __metadata:
languageName: node
linkType: hard
-"markdown-it@npm:13.0.2":
- version: 13.0.2
- resolution: "markdown-it@npm:13.0.2"
+"markdown-it@npm:14.1.0":
+ version: 14.1.0
+ resolution: "markdown-it@npm:14.1.0"
dependencies:
argparse: "npm:^2.0.1"
- entities: "npm:~3.0.1"
- linkify-it: "npm:^4.0.1"
- mdurl: "npm:^1.0.1"
- uc.micro: "npm:^1.0.5"
+ entities: "npm:^4.4.0"
+ linkify-it: "npm:^5.0.0"
+ mdurl: "npm:^2.0.0"
+ punycode.js: "npm:^2.3.1"
+ uc.micro: "npm:^2.1.0"
bin:
- markdown-it: bin/markdown-it.js
- checksum: 4fe0c41bc4c318c2901dc2923470c259cab137a4ab870001038877b942c9cc65072923e2d957f785de69a9da27c55657bd531607ccfd258246bd72a8deb8c2ee
+ markdown-it: bin/markdown-it.mjs
+ checksum: 9a6bb444181d2db7016a4173ae56a95a62c84d4cbfb6916a399b11d3e6581bf1cc2e4e1d07a2f022ae72c25f56db90fbe1e529fca16fbf9541659dc53480d4b4
+ languageName: node
+ linkType: hard
+
+"markdown-table@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "markdown-table@npm:2.0.0"
+ dependencies:
+ repeat-string: "npm:^1.0.0"
+ checksum: f257e0781ea50eb946919df84bdee4ba61f983971b277a369ca7276f89740fd0e2749b9b187163a42df4c48682b71962d4007215ce3523480028f06c11ddc2e6
languageName: node
linkType: hard
@@ -7614,47 +7928,62 @@ __metadata:
languageName: node
linkType: hard
-"markdownlint-cli2-formatter-default@npm:0.0.4":
- version: 0.0.4
- resolution: "markdownlint-cli2-formatter-default@npm:0.0.4"
+"markdownlint-cli2-formatter-default@npm:0.0.5":
+ version: 0.0.5
+ resolution: "markdownlint-cli2-formatter-default@npm:0.0.5"
peerDependencies:
markdownlint-cli2: ">=0.0.4"
- checksum: 8be8dc06e3ba132c09f4600f1e898634c239bad2ff7642a3255bdfbfec269c3b040e5315fdfc3dde91df2b10b474b618482fa84f0048f4080b682e68a4d11557
+ checksum: 7041a5833846d895054cf273c8e75efc13a03bbc88679cd48ea77240318232e883846037e984358a3ad3825fbb602d83492417ed6e36051bc5b603c4bedb3622
languageName: node
linkType: hard
-"markdownlint-cli2@npm:^0.11.0":
- version: 0.11.0
- resolution: "markdownlint-cli2@npm:0.11.0"
- dependencies:
- globby: "npm:14.0.0"
- markdownlint: "npm:0.32.1"
- markdownlint-cli2-formatter-default: "npm:0.0.4"
- micromatch: "npm:4.0.5"
- strip-json-comments: "npm:5.0.1"
- yaml: "npm:2.3.4"
+"markdownlint-cli2@npm:^0.14.0":
+ version: 0.14.0
+ resolution: "markdownlint-cli2@npm:0.14.0"
+ dependencies:
+ globby: "npm:14.0.2"
+ js-yaml: "npm:4.1.0"
+ jsonc-parser: "npm:3.3.1"
+ markdownlint: "npm:0.35.0"
+ markdownlint-cli2-formatter-default: "npm:0.0.5"
+ micromatch: "npm:4.0.8"
bin:
markdownlint-cli2: markdownlint-cli2.js
- markdownlint-cli2-config: markdownlint-cli2-config.js
- markdownlint-cli2-fix: markdownlint-cli2-fix.js
- checksum: 7ccc85d839ea7355738a37b6023960712bda7f09b3c92b44857ba4e7e8ba3a601c38bdc2ab79f29c925998f1ddf8b524359e045b2cef14d88932cf1211f9490f
+ checksum: cf2c65de97887a51e2ad756779fd90cabc6b26d09c07aed43422c142e0b2406a8a1e84e17cbf8590a72812e65d5a16e106d7110e392bb7f5fb154a09245bb985
languageName: node
linkType: hard
-"markdownlint-micromark@npm:0.1.7":
- version: 0.1.7
- resolution: "markdownlint-micromark@npm:0.1.7"
- checksum: d9d20cac1a7f20731c1abeb590147151b9f0ddf070125467e6cd769b9dfabf5c98bcb28f5dbc33d91bcb13ec8aadf79739145552af3751142417f887cc985b67
+"markdownlint-micromark@npm:0.1.10":
+ version: 0.1.10
+ resolution: "markdownlint-micromark@npm:0.1.10"
+ checksum: 1a392a3d92c01093244c15f69a658e68eeffe26b96218189509184246e19be9f64c7937241a5911f1ff2bd721f0d60f32242a46a9b3b6ab505ef22b8dbb66918
+ languageName: node
+ linkType: hard
+
+"markdownlint-micromark@npm:0.1.12":
+ version: 0.1.12
+ resolution: "markdownlint-micromark@npm:0.1.12"
+ checksum: 6833c2b9eb6fd63c43dde30aff8bc526cb97638b287535f8277e2c97015602df0670becdece639986dbe3ac2b279d7c1d308c0a65cb5d2aacc331ea768afa86e
+ languageName: node
+ linkType: hard
+
+"markdownlint@npm:0.35.0":
+ version: 0.35.0
+ resolution: "markdownlint@npm:0.35.0"
+ dependencies:
+ markdown-it: "npm:14.1.0"
+ markdownlint-micromark: "npm:0.1.10"
+ checksum: 32330f6e6c2a35e3505f4bdae5211c0b8bd9130604a0d93bb22506835447065a4efd9d3ecefaa7f7c6744628f8427fe98296b71948d2d1502a46917863235717
languageName: node
linkType: hard
-"markdownlint@npm:0.32.1, markdownlint@npm:^0.32.1":
- version: 0.32.1
- resolution: "markdownlint@npm:0.32.1"
+"markdownlint@npm:^0.36.1":
+ version: 0.36.1
+ resolution: "markdownlint@npm:0.36.1"
dependencies:
- markdown-it: "npm:13.0.2"
- markdownlint-micromark: "npm:0.1.7"
- checksum: be2fbb409daaab8916deefafcc4d4d1a3e7dad6d602c03f4bd14cfb762b41de335da181bae11340a1db57b74844cfbb3bcafe05d92a69c5f809b689d8c1bd4b2
+ markdown-it: "npm:14.1.0"
+ markdownlint-micromark: "npm:0.1.12"
+ checksum: 1f93a010c5421a9c9cbd51aeb4046c674b4797ef1c6ad55b0344e7a6ecec46dd38d526e623fd6a3d4c486fe594119c5161dad6033b6468f7719d3c69b5d0cea6
languageName: node
linkType: hard
@@ -7910,17 +8239,24 @@ __metadata:
languageName: node
linkType: hard
-"mdn-data@npm:2.0.14":
- version: 2.0.14
- resolution: "mdn-data@npm:2.0.14"
- checksum: 67241f8708c1e665a061d2b042d2d243366e93e5bf1f917693007f6d55111588b952dcbfd3ea9c2d0969fb754aad81b30fdcfdcc24546495fc3b24336b28d4bd
+"mdn-data@npm:2.0.28":
+ version: 2.0.28
+ resolution: "mdn-data@npm:2.0.28"
+ checksum: 20000932bc4cd1cde9cba4e23f08cc4f816398af4c15ec81040ed25421d6bf07b5cf6b17095972577fb498988f40f4cb589e3169b9357bb436a12d8e07e5ea7b
languageName: node
linkType: hard
-"mdurl@npm:^1.0.1":
- version: 1.0.1
- resolution: "mdurl@npm:1.0.1"
- checksum: ea8534341eb002aaa532a722daef6074cd8ca66202e10a2b4cda46722c1ebdb1da92197ac300bc953d3ef1bf41cd6561ef2cc69d82d5d0237dae00d4a61a4eee
+"mdn-data@npm:2.0.30":
+ version: 2.0.30
+ resolution: "mdn-data@npm:2.0.30"
+ checksum: a2c472ea16cee3911ae742593715aa4c634eb3d4b9f1e6ada0902aa90df13dcbb7285d19435f3ff213ebaa3b2e0c0265c1eb0e3fb278fda7f8919f046a410cd9
+ languageName: node
+ linkType: hard
+
+"mdurl@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "mdurl@npm:2.0.0"
+ checksum: 633db522272f75ce4788440669137c77540d74a83e9015666a9557a152c02e245b192edc20bc90ae953bbab727503994a53b236b4d9c99bdaee594d0e7dd2ce0
languageName: node
linkType: hard
@@ -8466,13 +8802,13 @@ __metadata:
languageName: node
linkType: hard
-"micromatch@npm:4.0.5, micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
- version: 4.0.5
- resolution: "micromatch@npm:4.0.5"
+"micromatch@npm:4.0.8, micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
+ version: 4.0.8
+ resolution: "micromatch@npm:4.0.8"
dependencies:
- braces: "npm:^3.0.2"
+ braces: "npm:^3.0.3"
picomatch: "npm:^2.3.1"
- checksum: 3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff
+ checksum: 166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8
languageName: node
linkType: hard
@@ -8499,7 +8835,7 @@ __metadata:
languageName: node
linkType: hard
-"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34":
+"mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34":
version: 2.1.35
resolution: "mime-types@npm:2.1.35"
dependencies:
@@ -8538,14 +8874,15 @@ __metadata:
languageName: node
linkType: hard
-"mini-css-extract-plugin@npm:^2.7.6":
- version: 2.7.6
- resolution: "mini-css-extract-plugin@npm:2.7.6"
+"mini-css-extract-plugin@npm:^2.9.1":
+ version: 2.9.2
+ resolution: "mini-css-extract-plugin@npm:2.9.2"
dependencies:
schema-utils: "npm:^4.0.0"
+ tapable: "npm:^2.2.1"
peerDependencies:
webpack: ^5.0.0
- checksum: 4862da928f52c18b37daa52d548c9f2a1ac65c900a48b63f7faa3354d8cfcd21618c049696559e73e2e27fc12d46748e6a490e0b885e54276429607d0d08c156
+ checksum: 5d3218dbd7db48b572925ddac05162a7415bf81b321f1a0c07016ec643cb5720c8a836ae68d45f5de826097a3013b601706c9c5aacb7f610dc2041b271de2ce0
languageName: node
linkType: hard
@@ -8574,7 +8911,7 @@ __metadata:
languageName: node
linkType: hard
-"minimist@npm:^1.2.0, minimist@npm:^1.2.8":
+"minimist@npm:^1.2.0":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
checksum: 19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
@@ -8704,7 +9041,7 @@ __metadata:
languageName: node
linkType: hard
-"ms@npm:2.1.3":
+"ms@npm:2.1.3, ms@npm:^2.1.3":
version: 2.1.3
resolution: "ms@npm:2.1.3"
checksum: d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
@@ -8723,16 +9060,7 @@ __metadata:
languageName: node
linkType: hard
-"nanoid@npm:3.3.6":
- version: 3.3.6
- resolution: "nanoid@npm:3.3.6"
- bin:
- nanoid: bin/nanoid.cjs
- checksum: 606b355960d0fcbe3d27924c4c52ef7d47d3b57208808ece73279420d91469b01ec1dce10fae512b6d4a8c5a5432b352b228336a8b2202a6ea68e67fa348e2ee
- languageName: node
- linkType: hard
-
-"nanoid@npm:^3.3.6":
+"nanoid@npm:3.3.7, nanoid@npm:^3.3.6, nanoid@npm:^3.3.7":
version: 3.3.7
resolution: "nanoid@npm:3.3.7"
bin:
@@ -8784,20 +9112,6 @@ __metadata:
languageName: node
linkType: hard
-"node-fetch@npm:^2.6.12":
- version: 2.7.0
- resolution: "node-fetch@npm:2.7.0"
- dependencies:
- whatwg-url: "npm:^5.0.0"
- peerDependencies:
- encoding: ^0.1.0
- peerDependenciesMeta:
- encoding:
- optional: true
- checksum: b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8
- languageName: node
- linkType: hard
-
"node-forge@npm:^1":
version: 1.3.1
resolution: "node-forge@npm:1.3.1"
@@ -8825,10 +9139,10 @@ __metadata:
languageName: node
linkType: hard
-"node-releases@npm:^2.0.13":
- version: 2.0.13
- resolution: "node-releases@npm:2.0.13"
- checksum: 2fb44bf70fc949d27f3a48a7fd1a9d1d603ddad4ccd091f26b3fb8b1da976605d919330d7388ccd55ca2ade0dc8b2e12841ba19ef249c8bb29bf82532d401af7
+"node-releases@npm:^2.0.18":
+ version: 2.0.18
+ resolution: "node-releases@npm:2.0.18"
+ checksum: 786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27
languageName: node
linkType: hard
@@ -8857,13 +9171,6 @@ __metadata:
languageName: node
linkType: hard
-"normalize-url@npm:^6.0.1":
- version: 6.1.0
- resolution: "normalize-url@npm:6.1.0"
- checksum: 95d948f9bdd2cfde91aa786d1816ae40f8262946e13700bf6628105994fe0ff361662c20af3961161c38a119dc977adeb41fc0b41b1745eb77edaaf9cb22db23
- languageName: node
- linkType: hard
-
"normalize-url@npm:^8.0.0":
version: 8.0.0
resolution: "normalize-url@npm:8.0.0"
@@ -8880,10 +9187,10 @@ __metadata:
languageName: node
linkType: hard
-"npm-to-yarn@npm:^2.0.0":
- version: 2.1.0
- resolution: "npm-to-yarn@npm:2.1.0"
- checksum: c2a406b74d12cf5b09a2eb3c51973f1232bc023bce383d0f8442be0dc17b4618ad4fcb2f0a2beca7bef046d778eb61bfefe6b24f4ac92fd17ebaa8bd5a6a7606
+"npm-to-yarn@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "npm-to-yarn@npm:3.0.0"
+ checksum: 2e0bba85dc4ac83d588da6a3636e4043beecb6360be76c110a982432ddc6c63fe181524aa767c97da4799fe80a104e0502901a177fb3a82f233722ded35a3a27
languageName: node
linkType: hard
@@ -8903,7 +9210,19 @@ __metadata:
languageName: node
linkType: hard
-"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1":
+"null-loader@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "null-loader@npm:4.0.1"
+ dependencies:
+ loader-utils: "npm:^2.0.0"
+ schema-utils: "npm:^3.0.0"
+ peerDependencies:
+ webpack: ^4.0.0 || ^5.0.0
+ checksum: fe9a74a928c9ddc1eab7be0e4322516439562d6efd6feeb0f7c61777d4b79a6a8e5a6bc8133deb59408f3f423bdf84c154a88168154a583154e9e33d544b4d42
+ languageName: node
+ linkType: hard
+
+"object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: 1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414
@@ -9252,10 +9571,10 @@ __metadata:
languageName: node
linkType: hard
-"path-to-regexp@npm:2.2.1":
- version: 2.2.1
- resolution: "path-to-regexp@npm:2.2.1"
- checksum: f4b51090a73dad5ce0720f13ce8528ac77914bc927d72cc4ba05ab32770ad3a8d2e431962734b688b9ed863d4098d858da6ff4746037e4e24259cbd3b2c32b79
+"path-to-regexp@npm:3.3.0":
+ version: 3.3.0
+ resolution: "path-to-regexp@npm:3.3.0"
+ checksum: ffa0ebe7088d38d435a8d08b0fe6e8c93ceb2a81a65d4dd1d9a538f52e09d5e3474ed5f553cb3b180d894b0caa10698a68737ab599fd1e56b4663d1a64c9f77b
languageName: node
linkType: hard
@@ -9293,10 +9612,10 @@ __metadata:
languageName: node
linkType: hard
-"picocolors@npm:^1.0.0":
- version: 1.0.0
- resolution: "picocolors@npm:1.0.0"
- checksum: 20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7
+"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0":
+ version: 1.1.1
+ resolution: "picocolors@npm:1.1.1"
+ checksum: e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
languageName: node
linkType: hard
@@ -9325,88 +9644,88 @@ __metadata:
languageName: node
linkType: hard
-"postcss-calc@npm:^8.2.3":
- version: 8.2.4
- resolution: "postcss-calc@npm:8.2.4"
+"postcss-calc@npm:^9.0.1":
+ version: 9.0.1
+ resolution: "postcss-calc@npm:9.0.1"
dependencies:
- postcss-selector-parser: "npm:^6.0.9"
+ postcss-selector-parser: "npm:^6.0.11"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
postcss: ^8.2.2
- checksum: 8518a429488c3283ff1560c83a511f6f772329bc61d88875eb7c83e13a8683b7ccbdccaa9946024cf1553da3eacd2f40fcbcebf1095f7fdeb432bf86bc6ba6ba
+ checksum: e0df07337162dbcaac5d6e030c7fd289e21da8766a9daca5d6b2b3c8094bb524ae5d74c70048ea7fe5fe4960ce048c60ac97922d917c3bbff34f58e9d2b0eb0e
languageName: node
linkType: hard
-"postcss-colormin@npm:^5.3.1":
- version: 5.3.1
- resolution: "postcss-colormin@npm:5.3.1"
+"postcss-colormin@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "postcss-colormin@npm:6.1.0"
dependencies:
- browserslist: "npm:^4.21.4"
+ browserslist: "npm:^4.23.0"
caniuse-api: "npm:^3.0.0"
- colord: "npm:^2.9.1"
+ colord: "npm:^2.9.3"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: c4ca6f335dd992dc8e3df24bffc3495c4e504eba8489c81cb6836fdce3203f423cf4c0b640c4b63c586f588c59d82adb5313c3c5d1a68113896d18ed71caa462
+ postcss: ^8.4.31
+ checksum: 0802963fa0d8f2fe408b2e088117670f5303c69a58c135f0ecf0e5ceff69e95e87111b22c4e29c9adb2f69aa8d3bc175f4e8e8708eeb99c9ffc36c17064de427
languageName: node
linkType: hard
-"postcss-convert-values@npm:^5.1.3":
- version: 5.1.3
- resolution: "postcss-convert-values@npm:5.1.3"
+"postcss-convert-values@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "postcss-convert-values@npm:6.1.0"
dependencies:
- browserslist: "npm:^4.21.4"
+ browserslist: "npm:^4.23.0"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: cd10a81781a12487b2921ff84a1a068e948a1956b9539a284c202abecf4cacdd3e106eb026026b22dbf70933f4315c824c111f6b71f56c355e47b842ca9b1dec
+ postcss: ^8.4.31
+ checksum: a80066965cb58fe8fcaf79f306b32c83fc678e1f0678e43f4db3e9fee06eed6db92cf30631ad348a17492769d44757400493c91a33ee865ee8dedea9234a11f5
languageName: node
linkType: hard
-"postcss-discard-comments@npm:^5.1.2":
- version: 5.1.2
- resolution: "postcss-discard-comments@npm:5.1.2"
+"postcss-discard-comments@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-discard-comments@npm:6.0.2"
peerDependencies:
- postcss: ^8.2.15
- checksum: cb5ba81623c498e18d406138e7d27d69fc668802a1139a8de69d28e80b3fe222cda7b634940512cae78d04f0c78afcd15d92bcf80e537c6c85fa8ff9cd61d00f
+ postcss: ^8.4.31
+ checksum: 338a1fcba7e2314d956e5e5b9bd1e12e6541991bf85ac72aed6e229a029bf60edb31f11576b677623576169aa7d9c75e1be259ac7b50d0b735b841b5518f9da9
languageName: node
linkType: hard
-"postcss-discard-duplicates@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-discard-duplicates@npm:5.1.0"
+"postcss-discard-duplicates@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "postcss-discard-duplicates@npm:6.0.3"
peerDependencies:
- postcss: ^8.2.15
- checksum: 3d3a49536c56097c06b4f085412e0cda0854fac1c559563ccb922d9fab6305ff13058cd6fee422aa66c1d7e466add4e7672d7ae2ff551a4af6f1a8d2142d471f
+ postcss: ^8.4.31
+ checksum: 24d2f00e54668f2837eb38a64b1751d7a4a73b2752f9749e61eb728f1fae837984bc2b339f7f5207aff5f66f72551253489114b59b9ba21782072677a81d7d1b
languageName: node
linkType: hard
-"postcss-discard-empty@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-discard-empty@npm:5.1.1"
+"postcss-discard-empty@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "postcss-discard-empty@npm:6.0.3"
peerDependencies:
- postcss: ^8.2.15
- checksum: 36c8b2197af836dbd93168c72cde4edc1f10fe00e564824119da076d3764909745bb60e4ada04052322e26872d1bce6a37c56815f1c48c813a21adca1a41fbdc
+ postcss: ^8.4.31
+ checksum: 1af08bb29f18eda41edf3602b257d89a4cf0a16f79fc773cfebd4a37251f8dbd9b77ac18efe55d0677d000b43a8adf2ef9328d31961c810e9433a38494a1fa65
languageName: node
linkType: hard
-"postcss-discard-overridden@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-discard-overridden@npm:5.1.0"
+"postcss-discard-overridden@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-discard-overridden@npm:6.0.2"
peerDependencies:
- postcss: ^8.2.15
- checksum: 7d3fc0b0d90599606fc083327a7c24390f90270a94a0119af4b74815d518948581579281f63b9bfa62e2644edf59bc9e725dc04ea5ba213f697804f3fb4dd8dc
+ postcss: ^8.4.31
+ checksum: fda70ef3cd4cb508369c5bbbae44d7760c40ec9f2e65df1cd1b6e0314317fb1d25ae7f64987ca84e66889c1e9d1862487a6ce391c159dfe04d536597bfc5030d
languageName: node
linkType: hard
-"postcss-discard-unused@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-discard-unused@npm:5.1.0"
+"postcss-discard-unused@npm:^6.0.5":
+ version: 6.0.5
+ resolution: "postcss-discard-unused@npm:6.0.5"
dependencies:
- postcss-selector-parser: "npm:^6.0.5"
+ postcss-selector-parser: "npm:^6.0.16"
peerDependencies:
- postcss: ^8.2.15
- checksum: eb7649eae1ef9987c397f4f533eb83f4245686317a5a0b468affd875d4d22778b62134e638198750efbaa41b7b7767995a91e5eb58d5fbbfe097506a3311102b
+ postcss: ^8.4.31
+ checksum: fca82f17395a7fcc78eab4e03dfb05958beb240c10cacb3836b832c6ea99f5259980c70890a9b7d8b67adf8071b61f3fcf1b432c7a116397aaf67909366da5cc
languageName: node
linkType: hard
@@ -9424,89 +9743,89 @@ __metadata:
languageName: node
linkType: hard
-"postcss-merge-idents@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-merge-idents@npm:5.1.1"
+"postcss-merge-idents@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "postcss-merge-idents@npm:6.0.3"
dependencies:
- cssnano-utils: "npm:^3.1.0"
+ cssnano-utils: "npm:^4.0.2"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 97552b831330a8055641d3aea7b9840c60922d22d7fefdaf109daa7dee543e48a93ea6189a5549798b3f29e66657bc5c520e76493a04f8f999b94a2c8fee6060
+ postcss: ^8.4.31
+ checksum: fdb51d971df33218bd5fdd9619e5a4d854e23affcea51f96bf4391260cb8d0bec937854582fa9a19bde1fa1b2a43fa5a2f179da23a3adeb8e8d292a4749a8ed7
languageName: node
linkType: hard
-"postcss-merge-longhand@npm:^5.1.7":
- version: 5.1.7
- resolution: "postcss-merge-longhand@npm:5.1.7"
+"postcss-merge-longhand@npm:^6.0.5":
+ version: 6.0.5
+ resolution: "postcss-merge-longhand@npm:6.0.5"
dependencies:
postcss-value-parser: "npm:^4.2.0"
- stylehacks: "npm:^5.1.1"
+ stylehacks: "npm:^6.1.1"
peerDependencies:
- postcss: ^8.2.15
- checksum: 4d9f44b03f19522cc81ae4f5b1f2a9ef2db918dbd8b3042d4f1b2461b2230b8ec1269334db6a67a863ba68f64cabd712e6e45340ddb22a3fc03cd34df69d2bf0
+ postcss: ^8.4.31
+ checksum: 5a223a7f698c05ab42e9997108a7ff27ea1e0c33a11a353d65a04fc89c3b5b750b9e749550d76b6406329117a055adfc79dde7fee48dca5c8e167a2854ae3fea
languageName: node
linkType: hard
-"postcss-merge-rules@npm:^5.1.4":
- version: 5.1.4
- resolution: "postcss-merge-rules@npm:5.1.4"
+"postcss-merge-rules@npm:^6.1.1":
+ version: 6.1.1
+ resolution: "postcss-merge-rules@npm:6.1.1"
dependencies:
- browserslist: "npm:^4.21.4"
+ browserslist: "npm:^4.23.0"
caniuse-api: "npm:^3.0.0"
- cssnano-utils: "npm:^3.1.0"
- postcss-selector-parser: "npm:^6.0.5"
+ cssnano-utils: "npm:^4.0.2"
+ postcss-selector-parser: "npm:^6.0.16"
peerDependencies:
- postcss: ^8.2.15
- checksum: e7686cdda052071bf98810ad381e26145c43a2286f9540f04f97ef93101604b78d478dd555db91e5f73751bb353c283ba75c2fcb16a3751ac7d93dc6a0130c41
+ postcss: ^8.4.31
+ checksum: 6d8952dbb19b1e59bf5affe0871fa1be6515103466857cff5af879d6cf619659f8642ec7a931cabb7cdbd393d8c1e91748bf70bee70fa3edea010d4e25786d04
languageName: node
linkType: hard
-"postcss-minify-font-values@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-minify-font-values@npm:5.1.0"
+"postcss-minify-font-values@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "postcss-minify-font-values@npm:6.1.0"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 7aa4f93a853b657f79a8b28d0e924cafce3720086d9da02ce04b8b2f8de42e18ce32c8f7f1078390fb5ec82468e2d8e771614387cea3563f05fd9fa1798e1c59
+ postcss: ^8.4.31
+ checksum: 0d6567170c22a7db42096b5eac298f041614890fbe01759a9fa5ccda432f2bb09efd399d92c11bf6675ae13ccd259db4602fad3c358317dee421df5f7ab0a003
languageName: node
linkType: hard
-"postcss-minify-gradients@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-minify-gradients@npm:5.1.1"
+"postcss-minify-gradients@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "postcss-minify-gradients@npm:6.0.3"
dependencies:
- colord: "npm:^2.9.1"
- cssnano-utils: "npm:^3.1.0"
+ colord: "npm:^2.9.3"
+ cssnano-utils: "npm:^4.0.2"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: bcb2802d7c8f0f76c7cff089884844f26c24b95f35c3ec951d7dec8c212495d1873d6ba62d6225ce264570e8e0668e271f9bc79bb6f5d2429c1f8933f4e3021d
+ postcss: ^8.4.31
+ checksum: 7fcbcec94fe5455b89fe1b424a451198e60e0407c894bbacdc062d9fdef2f8571b483b5c3bb17f22d2f1249431251b2de22e1e4e8b0614d10624f8ee6e71afd2
languageName: node
linkType: hard
-"postcss-minify-params@npm:^5.1.4":
- version: 5.1.4
- resolution: "postcss-minify-params@npm:5.1.4"
+"postcss-minify-params@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "postcss-minify-params@npm:6.1.0"
dependencies:
- browserslist: "npm:^4.21.4"
- cssnano-utils: "npm:^3.1.0"
+ browserslist: "npm:^4.23.0"
+ cssnano-utils: "npm:^4.0.2"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: debce6f0f7dd9af69b4bb9e467ea1ccccff2d849b6020461a2b9741c0c137340e6076c245dc2e83880180eb2e82936280fa31dfe8608e5a2e3618f3d864314c5
+ postcss: ^8.4.31
+ checksum: e5c38c3e5fb42e2ca165764f983716e57d854a63a477f7389ccc94cd2ab8123707006613bd7f29acc6eafd296fff513aa6d869c98ac52590f886d641cb21a59e
languageName: node
linkType: hard
-"postcss-minify-selectors@npm:^5.2.1":
- version: 5.2.1
- resolution: "postcss-minify-selectors@npm:5.2.1"
+"postcss-minify-selectors@npm:^6.0.4":
+ version: 6.0.4
+ resolution: "postcss-minify-selectors@npm:6.0.4"
dependencies:
- postcss-selector-parser: "npm:^6.0.5"
+ postcss-selector-parser: "npm:^6.0.16"
peerDependencies:
- postcss: ^8.2.15
- checksum: f3f4ec110f5f697cfc9dde3e491ff10aa07509bf33cc940aa539e4b5b643d1b9f8bb97f8bb83d05fc96f5eeb220500ebdeffbde513bd176c0671e21c2c96fab9
+ postcss: ^8.4.31
+ checksum: 695ec2e1e3a7812b0cabe1105d0ed491760be3d8e9433914fb5af1fc30a84e6dc24089cd31b7e300de620b8e7adf806526c1acf8dd14077a7d1d2820c60a327c
languageName: node
linkType: hard
@@ -9554,152 +9873,161 @@ __metadata:
languageName: node
linkType: hard
-"postcss-normalize-charset@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-normalize-charset@npm:5.1.0"
+"postcss-normalize-charset@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-charset@npm:6.0.2"
peerDependencies:
- postcss: ^8.2.15
- checksum: aa481584d4db48e0dbf820f992fa235e6c41ff3d4701a62d349f33c1ad4c5c7dcdea3096db9ff2a5c9497e9bed2186d594ccdb1b42d57b30f58affba5829ad9c
+ postcss: ^8.4.31
+ checksum: af32a3b4cf94163d728b8aa935b2494c9f69fbc96a33b35f67ae15dbdef7fcc8732569df97cbaaf20ca6c0103c39adad0cfce2ba07ffed283796787f6c36f410
languageName: node
linkType: hard
-"postcss-normalize-display-values@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-normalize-display-values@npm:5.1.0"
+"postcss-normalize-display-values@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-display-values@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 70b164fda885c097c02c98914fba4cd19b2382ff5f85f77e5315d88a1d477b4803f0f271d95a38e044e2a6c3b781c5c9bfb83222fc577199f2aeb0b8f4254e2f
+ postcss: ^8.4.31
+ checksum: 782761850c7e697fdb6c3ff53076de716a71b60f9e835efb2f7ef238de347c88b5d55f0d43cf5c608e1ee58de65360e3d9fccd5f20774bba08ded7c87d8a5651
languageName: node
linkType: hard
-"postcss-normalize-positions@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-normalize-positions@npm:5.1.1"
+"postcss-normalize-positions@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-positions@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 910d58991fd38a7cf6ed6471e6fa4a96349690ad1a99a02e8cac46d76ba5045f2fca453088b68b05ff665afd96dc617c4674c68acaeabbe83f502e4963fb78b1
+ postcss: ^8.4.31
+ checksum: 9fdd42a47226bbda5f68774f3c4c3a90eb4fa708aef5a997c6a52fe6cac06585c9774038fe3bc1aa86a203c29223b8d8db6ebe7580c1aa293154f2b48db0b038
languageName: node
linkType: hard
-"postcss-normalize-repeat-style@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-normalize-repeat-style@npm:5.1.1"
+"postcss-normalize-repeat-style@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-repeat-style@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 57c3817a2107ebb17e4ceee3831d230c72a3ccc7650f4d5f12aa54f6ea766777401f4f63b2615b721350b2e8c7ae0b0bbc3f1c5ad4e7fa737c9efb92cfa0cbb0
+ postcss: ^8.4.31
+ checksum: 9133ccbdf1286920c1cd0d01c1c5fa0bd3251b717f2f3e47d691dcc44978ac1dc419d20d9ae5428bd48ee542059e66b823ba699356f5968ccced5606c7c7ca34
languageName: node
linkType: hard
-"postcss-normalize-string@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-normalize-string@npm:5.1.0"
+"postcss-normalize-string@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-string@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: a5e9979998f478d385ddff865bdd8a4870af69fa8c91c9398572a299ff39b39a6bda922a48fab0d2cddc639f30159c39baaed880ed7d13cd27cc64eaa9400b3b
+ postcss: ^8.4.31
+ checksum: fecc2d52c4029b24fecf2ca2fb45df5dbdf9f35012194ad4ea80bc7be3252cdcb21a0976400902320595aa6178f2cc625cc804c6b6740aef6efa42105973a205
languageName: node
linkType: hard
-"postcss-normalize-timing-functions@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-normalize-timing-functions@npm:5.1.0"
+"postcss-normalize-timing-functions@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-timing-functions@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: afb34d8e313004ae8cd92910bf1a6eb9885f29ae803cd9032b6dfe7b67a9ad93f800976f10e55170b2b08fe9484825e9272629971186812c2764c73843268237
+ postcss: ^8.4.31
+ checksum: a22af0b3374704e59ae70bbbcc66b7029137e284f04e30a2ad548818d1540d6c1ed748dd8f689b9b6df5c1064085a00ad07b6f7e25ffaad49d4e661b616cdeae
languageName: node
linkType: hard
-"postcss-normalize-unicode@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-normalize-unicode@npm:5.1.1"
+"postcss-normalize-unicode@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "postcss-normalize-unicode@npm:6.1.0"
dependencies:
- browserslist: "npm:^4.21.4"
+ browserslist: "npm:^4.23.0"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: c102888d488d05c53ab10ffcd4e0efb892ef0cc2f9b0abe9c9b175a2d7a9c226981ca6806ed9e5c1b82a8190f2b3a8342a6de800f019b417130661b0787ff6d7
+ postcss: ^8.4.31
+ checksum: ff5746670d94dd97b49a0955c3c71ff516fb4f54bbae257f877d179bacc44a62e50a0fd6e7ddf959f2ca35c335de4266b0c275d880bb57ad7827189339ab1582
languageName: node
linkType: hard
-"postcss-normalize-url@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-normalize-url@npm:5.1.0"
+"postcss-normalize-url@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-url@npm:6.0.2"
dependencies:
- normalize-url: "npm:^6.0.1"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: a016cefd1ef80f74ef9dbed50593d3b533101e93aaadfc292896fddd8d6c3eb732a9fc5cb2e0d27f79c1f60f0fdfc40b045a494b514451e9610c6acf9392eb98
+ postcss: ^8.4.31
+ checksum: 4718f1c0657788d2c560b340ee8e0a4eb3eb053eba6fbbf489e9a6e739b4c5f9ce1957f54bd03497c50a1f39962bf6ab9ff6ba4976b69dd160f6afd1670d69b7
languageName: node
linkType: hard
-"postcss-normalize-whitespace@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-normalize-whitespace@npm:5.1.1"
+"postcss-normalize-whitespace@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-normalize-whitespace@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: d7b53dd90fe369bfb9838a40096db904a41f50dadfd04247ec07d7ab5588c3d4e70d1c7f930523bd061cb74e6683cef45c6e6c4eb57ea174ee3fc99f3de222d1
+ postcss: ^8.4.31
+ checksum: d5275a88e29a894aeb83a2a833e816d2456dbf3f39961628df596ce205dcc4895186a023812ff691945e0804241ccc53e520d16591b5812288474b474bbaf652
languageName: node
linkType: hard
-"postcss-ordered-values@npm:^5.1.3":
- version: 5.1.3
- resolution: "postcss-ordered-values@npm:5.1.3"
+"postcss-ordered-values@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-ordered-values@npm:6.0.2"
dependencies:
- cssnano-utils: "npm:^3.1.0"
+ cssnano-utils: "npm:^4.0.2"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 55abfbd2c7267eefed62a881ed0b5c0c98409c50a589526a3ebb9f8d879979203e523b8888fa84732bdd1ac887f721287a037002fa70c27c8d33f1bcbae9d9c6
+ postcss: ^8.4.31
+ checksum: aece23a289228aa804217a85f8da198d22b9123f02ca1310b81834af380d6fbe115e4300683599b4a2ab7f1c6a1dbd6789724c47c38e2b0a3774f2ea4b4f0963
languageName: node
linkType: hard
-"postcss-reduce-idents@npm:^5.2.0":
- version: 5.2.0
- resolution: "postcss-reduce-idents@npm:5.2.0"
+"postcss-reduce-idents@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "postcss-reduce-idents@npm:6.0.3"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: f7a6bc0caa531e7983c98a79d796e078ff8d02df1bb38357a5d7f11ddb5842d6777ab090fd811e889ab1a5e92ba2644c9a9e5e353f7c9f7ce85dbf1e07001c29
+ postcss: ^8.4.31
+ checksum: d9f9209e52ebb3d1d7feefc0be24fc74792e064e0fdec99554f050c6b882c61073d5d40986c545061b30e5ead881615e92c965dc765d8d83b2dec10d6a664e1f
languageName: node
linkType: hard
-"postcss-reduce-initial@npm:^5.1.2":
- version: 5.1.2
- resolution: "postcss-reduce-initial@npm:5.1.2"
+"postcss-reduce-initial@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "postcss-reduce-initial@npm:6.1.0"
dependencies:
- browserslist: "npm:^4.21.4"
+ browserslist: "npm:^4.23.0"
caniuse-api: "npm:^3.0.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: ddb2ce61c8d0997184f08200eafdf32b3c67e88228fee960f5e2010c32da0c1d8ea07712585bf2b3aaa15f583066401d45db2c1131527c5116ca6794ebebd865
+ postcss: ^8.4.31
+ checksum: a8f28cf51ce9a1b9423cce1a01c1d7cbee90125930ec36435a0073e73aef402d90affe2fd3600c964b679cf738869fda447b95a9acce74414e9d67d5c6ba8646
languageName: node
linkType: hard
-"postcss-reduce-transforms@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-reduce-transforms@npm:5.1.0"
+"postcss-reduce-transforms@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-reduce-transforms@npm:6.0.2"
dependencies:
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: caefaeb78652ad8701b94e91500e38551255e4899fa298a7357519a36cbeebae088eab4535e00f17675a1230f448c4a7077045639d496da4614a46bc41df4add
+ postcss: ^8.4.31
+ checksum: 755ef27b3d083f586ac831f0c611a66e76f504d27e2100dc7674f6b86afad597901b4520cb889fe58ca70e852aa7fd0c0acb69a63d39dfe6a95860b472394e7c
+ languageName: node
+ linkType: hard
+
+"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.16":
+ version: 6.1.2
+ resolution: "postcss-selector-parser@npm:6.1.2"
+ dependencies:
+ cssesc: "npm:^3.0.0"
+ util-deprecate: "npm:^1.0.2"
+ checksum: 523196a6bd8cf660bdf537ad95abd79e546d54180f9afb165a4ab3e651ac705d0f8b8ce6b3164fb9e3279ce482c5f751a69eb2d3a1e8eb0fd5e82294fb3ef13e
languageName: node
linkType: hard
-"postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9":
+"postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4":
version: 6.0.13
resolution: "postcss-selector-parser@npm:6.0.13"
dependencies:
@@ -9709,37 +10037,37 @@ __metadata:
languageName: node
linkType: hard
-"postcss-sort-media-queries@npm:^4.4.1":
- version: 4.4.1
- resolution: "postcss-sort-media-queries@npm:4.4.1"
+"postcss-sort-media-queries@npm:^5.2.0":
+ version: 5.2.0
+ resolution: "postcss-sort-media-queries@npm:5.2.0"
dependencies:
- sort-css-media-queries: "npm:2.1.0"
+ sort-css-media-queries: "npm:2.2.0"
peerDependencies:
- postcss: ^8.4.16
- checksum: 8bbc604daee29dc3e1f5090df972599c3c0eb08b37650e16c134a040cc1357484a48bbe03dac2977d616be1d490cde2934226fa1e6f7e52f4f5e7bf8f57e98d6
+ postcss: ^8.4.23
+ checksum: 5e7f265a21999bdbf6592f7e15b3e889dd93bc9b15fe048958e8f85603ac276e69ef50305e8b41b10f4eea68917c9c25c7956fa9c3ba7f8577c1149416d35c4e
languageName: node
linkType: hard
-"postcss-svgo@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-svgo@npm:5.1.0"
+"postcss-svgo@npm:^6.0.3":
+ version: 6.0.3
+ resolution: "postcss-svgo@npm:6.0.3"
dependencies:
postcss-value-parser: "npm:^4.2.0"
- svgo: "npm:^2.7.0"
+ svgo: "npm:^3.2.0"
peerDependencies:
- postcss: ^8.2.15
- checksum: 309634a587e38fef244648bc9cd1817e12144868d24f1173d87b1edc14a4a7fca614962b2cb9d93f4801e11bd8d676083986ad40ebab4438cb84731ce1571994
+ postcss: ^8.4.31
+ checksum: 994b15a88cbb411f32cfa98957faa5623c76f2d75fede51f5f47238f06b367ebe59c204fecbdaf21ccb9e727239a4b290087e04c502392658a0c881ddfbd61f2
languageName: node
linkType: hard
-"postcss-unique-selectors@npm:^5.1.1":
- version: 5.1.1
- resolution: "postcss-unique-selectors@npm:5.1.1"
+"postcss-unique-selectors@npm:^6.0.4":
+ version: 6.0.4
+ resolution: "postcss-unique-selectors@npm:6.0.4"
dependencies:
- postcss-selector-parser: "npm:^6.0.5"
+ postcss-selector-parser: "npm:^6.0.16"
peerDependencies:
- postcss: ^8.2.15
- checksum: 484f6409346d6244c134c5cdcd62f4f2751b269742f95222f13d8bac5fb224471ffe04e28a354670cbe0bdc2707778ead034fc1b801b473ffcbea5436807de30
+ postcss: ^8.4.31
+ checksum: bfb99d8a7c675c93f2e65c9d9d563477bfd46fdce9e2727d42d57982b31ccbaaf944e8034bfbefe48b3119e77fba7eb1b181c19b91cb3a5448058fa66a7c9ae9
languageName: node
linkType: hard
@@ -9750,16 +10078,16 @@ __metadata:
languageName: node
linkType: hard
-"postcss-zindex@npm:^5.1.0":
- version: 5.1.0
- resolution: "postcss-zindex@npm:5.1.0"
+"postcss-zindex@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "postcss-zindex@npm:6.0.2"
peerDependencies:
- postcss: ^8.2.15
- checksum: f739d3c0dec3875c770d6a101bc6ac1ccf545b0121e75b7fade911ad6ce454a2af87e6c3587c80a76a00f217e1761778f2083c2807eb78c17bfc53624b625ded
+ postcss: ^8.4.31
+ checksum: 346291703e1f2dd954144d2bb251713dad6ae10e8aa05c3873dee2fc7a30d72da7866bec060abd932b9b839bc1495f73d813dde5312750a69d7ad33c435ce7ea
languageName: node
linkType: hard
-"postcss@npm:^8.4.17, postcss@npm:^8.4.21, postcss@npm:^8.4.26":
+"postcss@npm:^8.4.21, postcss@npm:^8.4.26":
version: 8.4.31
resolution: "postcss@npm:8.4.31"
dependencies:
@@ -9770,6 +10098,26 @@ __metadata:
languageName: node
linkType: hard
+"postcss@npm:^8.4.24, postcss@npm:^8.4.38":
+ version: 8.4.47
+ resolution: "postcss@npm:8.4.47"
+ dependencies:
+ nanoid: "npm:^3.3.7"
+ picocolors: "npm:^1.1.0"
+ source-map-js: "npm:^1.2.1"
+ checksum: 929f68b5081b7202709456532cee2a145c1843d391508c5a09de2517e8c4791638f71dd63b1898dba6712f8839d7a6da046c72a5e44c162e908f5911f57b5f44
+ languageName: node
+ linkType: hard
+
+"prettier@npm:^3.3.3":
+ version: 3.3.3
+ resolution: "prettier@npm:3.3.3"
+ bin:
+ prettier: bin/prettier.cjs
+ checksum: b85828b08e7505716324e4245549b9205c0cacb25342a030ba8885aba2039a115dbcf75a0b7ca3b37bc9d101ee61fab8113fc69ca3359f2a226f1ecc07ad2e26
+ languageName: node
+ linkType: hard
+
"pretty-error@npm:^4.0.0":
version: 4.0.0
resolution: "pretty-error@npm:4.0.0"
@@ -9787,15 +10135,15 @@ __metadata:
languageName: node
linkType: hard
-"prism-react-renderer@npm:^2.1.0, prism-react-renderer@npm:^2.3.0":
- version: 2.3.0
- resolution: "prism-react-renderer@npm:2.3.0"
+"prism-react-renderer@npm:^2.3.0, prism-react-renderer@npm:^2.4.0":
+ version: 2.4.0
+ resolution: "prism-react-renderer@npm:2.4.0"
dependencies:
"@types/prismjs": "npm:^1.26.0"
clsx: "npm:^2.0.0"
peerDependencies:
react: ">=16.0.0"
- checksum: aa8fb176e156ebb1f8ca46d82966d37176f46545e03669ddab7d56479f915b41e95b02accc16af9e2e95c7fcd57ce6222d8eac08977c757d9c49c32c7b0e03ff
+ checksum: 3d6969b057da0efe39e3e637bf93601cd5757de5919180e8df16daf1d1b8eedc39b70c7f6f28724fba0a01bc857c6b78312ab027f4e913159d1165c5aba235bb
languageName: node
linkType: hard
@@ -9830,15 +10178,6 @@ __metadata:
languageName: node
linkType: hard
-"promise@npm:^7.1.1":
- version: 7.3.1
- resolution: "promise@npm:7.3.1"
- dependencies:
- asap: "npm:~2.0.3"
- checksum: 742e5c0cc646af1f0746963b8776299701ad561ce2c70b49365d62c8db8ea3681b0a1bf0d4e2fe07910bf72f02d39e51e8e73dc8d7503c3501206ac908be107f
- languageName: node
- linkType: hard
-
"prompts@npm:^2.4.2":
version: 2.4.2
resolution: "prompts@npm:2.4.2"
@@ -9884,17 +10223,10 @@ __metadata:
languageName: node
linkType: hard
-"proxy-from-env@npm:^1.1.0":
- version: 1.1.0
- resolution: "proxy-from-env@npm:1.1.0"
- checksum: fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b
- languageName: node
- linkType: hard
-
-"punycode@npm:^1.3.2":
- version: 1.4.1
- resolution: "punycode@npm:1.4.1"
- checksum: 354b743320518aef36f77013be6e15da4db24c2b4f62c5f1eb0529a6ed02fbaf1cb52925785f6ab85a962f2b590d9cd5ad730b70da72b5f180e2556b8bd3ca08
+"punycode.js@npm:^2.3.1":
+ version: 2.3.1
+ resolution: "punycode.js@npm:2.3.1"
+ checksum: 1d12c1c0e06127fa5db56bd7fdf698daf9a78104456a6b67326877afc21feaa821257b171539caedd2f0524027fa38e67b13dd094159c8d70b6d26d2bea4dfdb
languageName: node
linkType: hard
@@ -9914,13 +10246,6 @@ __metadata:
languageName: node
linkType: hard
-"pure-color@npm:^1.2.0":
- version: 1.3.0
- resolution: "pure-color@npm:1.3.0"
- checksum: 50d0e088ad0349bdd508cddf7c7afbb2d14ba3c047628dbfcfddf467a98f10462caf91f3227172ada88f64afaf761c499ecba0d4053b06926f0f914769be24b9
- languageName: node
- linkType: hard
-
"qs@npm:6.11.0":
version: 6.11.0
resolution: "qs@npm:6.11.0"
@@ -10014,18 +10339,6 @@ __metadata:
languageName: node
linkType: hard
-"react-base16-styling@npm:~0.6.0":
- version: 0.6.0
- resolution: "react-base16-styling@npm:0.6.0"
- dependencies:
- base16: "npm:^1.0.0"
- lodash.curry: "npm:^4.0.1"
- lodash.flow: "npm:^3.3.0"
- pure-color: "npm:^1.2.0"
- checksum: 4887ac57b36fedc7e1ebc99ae431c5feb07d60a9150770d0ca3a59f4ae7059434ea8813ca4f915e7434d4d8d8529b9ba072ceb85041fd52ca1cd6289c57c9621
- languageName: node
- linkType: hard
-
"react-dev-utils@npm:^12.0.1":
version: 12.0.1
resolution: "react-dev-utils@npm:12.0.1"
@@ -10058,15 +10371,15 @@ __metadata:
languageName: node
linkType: hard
-"react-dom@npm:^18.2.0":
- version: 18.2.0
- resolution: "react-dom@npm:18.2.0"
+"react-dom@npm:^18.3.1":
+ version: 18.3.1
+ resolution: "react-dom@npm:18.3.1"
dependencies:
loose-envify: "npm:^1.1.0"
- scheduler: "npm:^0.23.0"
+ scheduler: "npm:^0.23.2"
peerDependencies:
- react: ^18.2.0
- checksum: 66dfc5f93e13d0674e78ef41f92ed21dfb80f9c4ac4ac25a4b51046d41d4d2186abc915b897f69d3d0ebbffe6184e7c5876f2af26bfa956f179225d921be713a
+ react: ^18.3.1
+ checksum: a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85
languageName: node
linkType: hard
@@ -10128,10 +10441,12 @@ __metadata:
languageName: node
linkType: hard
-"react-lifecycles-compat@npm:~3.0.4":
- version: 3.0.4
- resolution: "react-lifecycles-compat@npm:3.0.4"
- checksum: 1d0df3c85af79df720524780f00c064d53a9dd1899d785eddb7264b378026979acbddb58a4b7e06e7d0d12aa1494fd5754562ee55d32907b15601068dae82c27
+"react-json-view-lite@npm:^1.2.0":
+ version: 1.5.0
+ resolution: "react-json-view-lite@npm:1.5.0"
+ peerDependencies:
+ react: ^16.13.1 || ^17.0.0 || ^18.0.0
+ checksum: e707717cb6b9d6cca5b138cdfb066e35ee7e493d1c88d4497e3a3a42b7651c8ff924ff53ad2da142a12b23b11379d39f38d8eee278c98c46cd6bc8844864b285
languageName: node
linkType: hard
@@ -10147,26 +10462,39 @@ __metadata:
languageName: node
linkType: hard
+"react-loadable@npm:@docusaurus/react-loadable@6.0.0":
+ version: 6.0.0
+ resolution: "@docusaurus/react-loadable@npm:6.0.0"
+ dependencies:
+ "@types/react": "npm:*"
+ peerDependencies:
+ react: "*"
+ checksum: 6b145d1a8d2e7342ceef58dd154aa990322f72a6cb98955ab8ce8e3f0dc7f0c5d00f9c2e4efa8d356c5effed72a130b5588857332b11faba0398f5429b484b04
+ languageName: node
+ linkType: hard
+
"react-navigation-website-next@workspace:.":
version: 0.0.0-use.local
resolution: "react-navigation-website-next@workspace:."
dependencies:
- "@docusaurus/core": "npm:3.0.0"
- "@docusaurus/plugin-client-redirects": "npm:3.0.0"
- "@docusaurus/plugin-google-analytics": "npm:3.0.0"
- "@docusaurus/preset-classic": "npm:3.0.0"
- "@docusaurus/remark-plugin-npm2yarn": "npm:3.0.0"
- "@octokit/graphql": "npm:^7.0.2"
- "@react-navigation/core": "npm:^7.0.0-alpha.2"
+ "@docusaurus/core": "npm:3.6.1"
+ "@docusaurus/faster": "npm:3.6.1"
+ "@docusaurus/plugin-client-redirects": "npm:3.6.1"
+ "@docusaurus/plugin-google-analytics": "npm:3.6.1"
+ "@docusaurus/preset-classic": "npm:3.6.1"
+ "@docusaurus/remark-plugin-npm2yarn": "npm:3.6.1"
+ "@octokit/graphql": "npm:^7.1.0"
+ "@react-navigation/core": "npm:^7.0.4"
escape-html: "npm:^1.0.3"
- markdownlint: "npm:^0.32.1"
- markdownlint-cli2: "npm:^0.11.0"
+ markdownlint: "npm:^0.36.1"
+ markdownlint-cli2: "npm:^0.14.0"
mkdirp: "npm:^3.0.1"
netlify-plugin-cache: "npm:^1.0.3"
- prism-react-renderer: "npm:^2.3.0"
- react: "npm:^18.2.0"
- react-dom: "npm:^18.2.0"
- react-simple-code-editor: "npm:^0.13.1"
+ prettier: "npm:^3.3.3"
+ prism-react-renderer: "npm:^2.4.0"
+ react: "npm:^18.3.1"
+ react-dom: "npm:^18.3.1"
+ react-simple-code-editor: "npm:^0.14.1"
languageName: unknown
linkType: soft
@@ -10218,35 +10546,22 @@ __metadata:
languageName: node
linkType: hard
-"react-simple-code-editor@npm:^0.13.1":
- version: 0.13.1
- resolution: "react-simple-code-editor@npm:0.13.1"
- peerDependencies:
- react: "*"
- react-dom: "*"
- checksum: 3d5346b43bd2bf32618f265cc36fb10702b543d0b9eee4600e68483c2c83205fdf6f18b1a665fbe8581ed84bb9e55ee379870e280801eec81b52bb5722c2d485
- languageName: node
- linkType: hard
-
-"react-textarea-autosize@npm:~8.3.2":
- version: 8.3.4
- resolution: "react-textarea-autosize@npm:8.3.4"
- dependencies:
- "@babel/runtime": "npm:^7.10.2"
- use-composed-ref: "npm:^1.3.0"
- use-latest: "npm:^1.2.1"
+"react-simple-code-editor@npm:^0.14.1":
+ version: 0.14.1
+ resolution: "react-simple-code-editor@npm:0.14.1"
peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 02dd38f6c40c4dd88b6c35370eaddc385c0a417c614b5ecb50d1121e99905da26fea9d5c05b580404b7f8a7d9a4964a8613654882be03963c36005779b96cca5
+ react: ">=16.8.0"
+ react-dom: ">=16.8.0"
+ checksum: 63264fce03315c80de4fc65b9e0a30b359cb0a6c269a90ad67ccff36c21d0f3ba1f9ac9bdfbe76477fc9a6d7033182debc64a58345f4914f0bc0b416eb686e61
languageName: node
linkType: hard
-"react@npm:^18.2.0":
- version: 18.2.0
- resolution: "react@npm:18.2.0"
+"react@npm:^18.3.1":
+ version: 18.3.1
+ resolution: "react@npm:18.3.1"
dependencies:
loose-envify: "npm:^1.1.0"
- checksum: b562d9b569b0cb315e44b48099f7712283d93df36b19a39a67c254c6686479d3980b7f013dc931f4a5a3ae7645eae6386b4aa5eea933baa54ecd0f9acb0902b8
+ checksum: 283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3
languageName: node
linkType: hard
@@ -10310,12 +10625,12 @@ __metadata:
languageName: node
linkType: hard
-"regenerate-unicode-properties@npm:^10.1.0":
- version: 10.1.1
- resolution: "regenerate-unicode-properties@npm:10.1.1"
+"regenerate-unicode-properties@npm:^10.2.0":
+ version: 10.2.0
+ resolution: "regenerate-unicode-properties@npm:10.2.0"
dependencies:
regenerate: "npm:^1.4.2"
- checksum: 89adb5ee5ba081380c78f9057c02e156a8181969f6fcca72451efc45612e0c3df767b4333f8d8479c274d9c6fe52ec4854f0d8a22ef95dccbe87da8e5f2ac77d
+ checksum: 5510785eeaf56bbfdf4e663d6753f125c08d2a372d4107bc1b756b7bf142e2ed80c2733a8b54e68fb309ba37690e66a0362699b0e21d5c1f0255dea1b00e6460
languageName: node
linkType: hard
@@ -10342,17 +10657,17 @@ __metadata:
languageName: node
linkType: hard
-"regexpu-core@npm:^5.3.1":
- version: 5.3.2
- resolution: "regexpu-core@npm:5.3.2"
+"regexpu-core@npm:^6.1.1":
+ version: 6.1.1
+ resolution: "regexpu-core@npm:6.1.1"
dependencies:
- "@babel/regjsgen": "npm:^0.8.0"
regenerate: "npm:^1.4.2"
- regenerate-unicode-properties: "npm:^10.1.0"
- regjsparser: "npm:^0.9.1"
+ regenerate-unicode-properties: "npm:^10.2.0"
+ regjsgen: "npm:^0.8.0"
+ regjsparser: "npm:^0.11.0"
unicode-match-property-ecmascript: "npm:^2.0.0"
unicode-match-property-value-ecmascript: "npm:^2.1.0"
- checksum: 7945d5ab10c8bbed3ca383d4274687ea825aee4ab93a9c51c6e31e1365edd5ea807f6908f800ba017b66c462944ba68011164e7055207747ab651f8111ef3770
+ checksum: 07d49697e20f9b65977535abba4858b7f5171c13f7c366be53ec1886d3d5f69f1b98cc6a6e63cf271adda077c3366a4c851c7473c28bbd69cf5a6b6b008efc3e
languageName: node
linkType: hard
@@ -10374,14 +10689,21 @@ __metadata:
languageName: node
linkType: hard
-"regjsparser@npm:^0.9.1":
- version: 0.9.1
- resolution: "regjsparser@npm:0.9.1"
+"regjsgen@npm:^0.8.0":
+ version: 0.8.0
+ resolution: "regjsgen@npm:0.8.0"
+ checksum: 44f526c4fdbf0b29286101a282189e4dbb303f4013cf3fea058668d96d113b9180d3d03d1e13f6d4cbde38b7728bf951aecd9dc199938c080093a9a6f0d7a6bd
+ languageName: node
+ linkType: hard
+
+"regjsparser@npm:^0.11.0":
+ version: 0.11.2
+ resolution: "regjsparser@npm:0.11.2"
dependencies:
- jsesc: "npm:~0.5.0"
+ jsesc: "npm:~3.0.2"
bin:
regjsparser: bin/parser
- checksum: fe44fcf19a99fe4f92809b0b6179530e5ef313ff7f87df143b08ce9a2eb3c4b6189b43735d645be6e8f4033bfb015ed1ca54f0583bc7561bed53fd379feb8225
+ checksum: 764e762de1b26a0cf48b45728fc1b2087f9c55bd4cea858cce28e4d5544c237f3f2dd6d40e2c41b80068e9cb92cc7d731a4285bc1f27d6ebc227792c70e4af1b
languageName: node
linkType: hard
@@ -10513,6 +10835,13 @@ __metadata:
languageName: node
linkType: hard
+"repeat-string@npm:^1.0.0":
+ version: 1.6.1
+ resolution: "repeat-string@npm:1.6.1"
+ checksum: 87fa21bfdb2fbdedc44b9a5b118b7c1239bdd2c2c1e42742ef9119b7d412a5137a1d23f1a83dc6bb686f4f27429ac6f542e3d923090b44181bafa41e8ac0174d
+ languageName: node
+ linkType: hard
+
"require-from-string@npm:^2.0.2":
version: 2.0.2
resolution: "require-from-string@npm:2.0.2"
@@ -10652,15 +10981,6 @@ __metadata:
languageName: node
linkType: hard
-"rxjs@npm:^7.8.1":
- version: 7.8.1
- resolution: "rxjs@npm:7.8.1"
- dependencies:
- tslib: "npm:^2.1.0"
- checksum: 3c49c1ecd66170b175c9cacf5cef67f8914dcbc7cd0162855538d365c83fea631167cacb644b3ce533b2ea0e9a4d0b12175186985f89d75abe73dbd8f7f06f68
- languageName: node
- linkType: hard
-
"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1":
version: 5.1.2
resolution: "safe-buffer@npm:5.1.2"
@@ -10689,12 +11009,12 @@ __metadata:
languageName: node
linkType: hard
-"scheduler@npm:^0.23.0":
- version: 0.23.0
- resolution: "scheduler@npm:0.23.0"
+"scheduler@npm:^0.23.2":
+ version: 0.23.2
+ resolution: "scheduler@npm:0.23.2"
dependencies:
loose-envify: "npm:^1.1.0"
- checksum: b777f7ca0115e6d93e126ac490dbd82642d14983b3079f58f35519d992fa46260be7d6e6cede433a92db70306310c6f5f06e144f0e40c484199e09c1f7be53dd
+ checksum: 26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78
languageName: node
linkType: hard
@@ -10720,7 +11040,7 @@ __metadata:
languageName: node
linkType: hard
-"schema-utils@npm:^4.0.0":
+"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1":
version: 4.2.0
resolution: "schema-utils@npm:4.2.0"
dependencies:
@@ -10818,19 +11138,18 @@ __metadata:
languageName: node
linkType: hard
-"serve-handler@npm:^6.1.5":
- version: 6.1.5
- resolution: "serve-handler@npm:6.1.5"
+"serve-handler@npm:^6.1.6":
+ version: 6.1.6
+ resolution: "serve-handler@npm:6.1.6"
dependencies:
bytes: "npm:3.0.0"
content-disposition: "npm:0.5.2"
- fast-url-parser: "npm:1.1.3"
mime-types: "npm:2.1.18"
minimatch: "npm:3.1.2"
path-is-inside: "npm:1.0.2"
- path-to-regexp: "npm:2.2.1"
+ path-to-regexp: "npm:3.3.0"
range-parser: "npm:1.2.0"
- checksum: 6fd393ae37a0305107e634ca545322b00605322189fe70d8f1a4a90a101c4e354768c610efe5a7ef1af3820cec5c33d97467c88151f35a3cb41d8ff2075ef802
+ checksum: 1e1cb6bbc51ee32bc1505f2e0605bdc2e96605c522277c977b67f83be9d66bd1eec8604388714a4d728e036d86b629bc9aec02120ea030d3d2c3899d44696503
languageName: node
linkType: hard
@@ -10873,13 +11192,6 @@ __metadata:
languageName: node
linkType: hard
-"setimmediate@npm:^1.0.5":
- version: 1.0.5
- resolution: "setimmediate@npm:1.0.5"
- checksum: 5bae81bfdbfbd0ce992893286d49c9693c82b1bcc00dcaaf3a09c8f428fdeacf4190c013598b81875dfac2b08a572422db7df779a99332d0fce186d15a3e4d49
- languageName: node
- linkType: hard
-
"setprototypeof@npm:1.1.0":
version: 1.1.0
resolution: "setprototypeof@npm:1.1.0"
@@ -11040,6 +11352,16 @@ __metadata:
languageName: node
linkType: hard
+"snake-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "snake-case@npm:3.0.4"
+ dependencies:
+ dot-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ checksum: ab19a913969f58f4474fe9f6e8a026c8a2142a01f40b52b79368068343177f818cdfef0b0c6b9558f298782441d5ca8ed5932eb57822439fad791d866e62cecd
+ languageName: node
+ linkType: hard
+
"sockjs@npm:^0.3.24":
version: 0.3.24
resolution: "sockjs@npm:0.3.24"
@@ -11072,10 +11394,17 @@ __metadata:
languageName: node
linkType: hard
-"sort-css-media-queries@npm:2.1.0":
- version: 2.1.0
- resolution: "sort-css-media-queries@npm:2.1.0"
- checksum: 6b39dd2503d8279688fee837c63bdf3b49eea14d10d5ae09d9e99e4a0b3da1b702c3931e8f793b702b9ea8929a9389ba8d6345b58b5d1f0ec3e84920685a724a
+"sort-css-media-queries@npm:2.2.0":
+ version: 2.2.0
+ resolution: "sort-css-media-queries@npm:2.2.0"
+ checksum: 7478308c7ca93409f959ab993d41de2f0515ed5f51b671908ecb777aae0d63be97b454d59d80e14ee4874884618a2e825d4ae7ccb225779276904dd175f4e766
+ languageName: node
+ linkType: hard
+
+"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "source-map-js@npm:1.2.1"
+ checksum: 7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf
languageName: node
linkType: hard
@@ -11096,7 +11425,7 @@ __metadata:
languageName: node
linkType: hard
-"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0":
+"source-map@npm:^0.6.0, source-map@npm:~0.6.0":
version: 0.6.1
resolution: "source-map@npm:0.6.1"
checksum: ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011
@@ -11174,13 +11503,6 @@ __metadata:
languageName: node
linkType: hard
-"stable@npm:^0.1.8":
- version: 0.1.8
- resolution: "stable@npm:0.1.8"
- checksum: df74b5883075076e78f8e365e4068ecd977af6c09da510cfc3148a303d4b87bc9aa8f7c48feb67ed4ef970b6140bd9eabba2129e28024aa88df5ea0114cba39d
- languageName: node
- linkType: hard
-
"statuses@npm:2.0.1":
version: 2.0.1
resolution: "statuses@npm:2.0.1"
@@ -11195,10 +11517,10 @@ __metadata:
languageName: node
linkType: hard
-"std-env@npm:^3.0.1":
- version: 3.5.0
- resolution: "std-env@npm:3.5.0"
- checksum: 0ba4efdaa2f2f9cce980be651732f6fe60011702375b376eea1d2cbca281065f8e7f3c58cec7f0b886db5fb0e427c144a50fd555529cffbcbb7b65b6457136da
+"std-env@npm:^3.7.0":
+ version: 3.7.0
+ resolution: "std-env@npm:3.7.0"
+ checksum: 60edf2d130a4feb7002974af3d5a5f3343558d1ccf8d9b9934d225c638606884db4a20d2fe6440a09605bca282af6b042ae8070a10490c0800d69e82e478f41e
languageName: node
linkType: hard
@@ -11302,13 +11624,6 @@ __metadata:
languageName: node
linkType: hard
-"strip-json-comments@npm:5.0.1":
- version: 5.0.1
- resolution: "strip-json-comments@npm:5.0.1"
- checksum: c9d9d55a0167c57aa688df3aa20628cf6f46f0344038f189eaa9d159978e80b2bfa6da541a40d83f7bde8a3554596259bf6b70578b2172356536a0e3fa5a0982
- languageName: node
- linkType: hard
-
"strip-json-comments@npm:^3.1.1":
version: 3.1.1
resolution: "strip-json-comments@npm:3.1.1"
@@ -11332,15 +11647,15 @@ __metadata:
languageName: node
linkType: hard
-"stylehacks@npm:^5.1.1":
- version: 5.1.1
- resolution: "stylehacks@npm:5.1.1"
+"stylehacks@npm:^6.1.1":
+ version: 6.1.1
+ resolution: "stylehacks@npm:6.1.1"
dependencies:
- browserslist: "npm:^4.21.4"
- postcss-selector-parser: "npm:^6.0.4"
+ browserslist: "npm:^4.23.0"
+ postcss-selector-parser: "npm:^6.0.16"
peerDependencies:
- postcss: ^8.2.15
- checksum: 402c2b545eeda0e972f125779adddc88df11bcf3a89de60c92026bd98cd49c1abffcd5bfe41766398835e0a1c7e5e72bdb6905809ecbb60716cd8d3a32ea7cd3
+ postcss: ^8.4.31
+ checksum: 2dd2bccfd8311ff71492e63a7b8b86c3d7b1fff55d4ba5a2357aff97743e633d351cdc2f5ae3c0057637d00dab4ef5fc5b218a1b370e4585a41df22b5a5128be
languageName: node
linkType: hard
@@ -11385,20 +11700,32 @@ __metadata:
languageName: node
linkType: hard
-"svgo@npm:^2.7.0, svgo@npm:^2.8.0":
- version: 2.8.0
- resolution: "svgo@npm:2.8.0"
+"svgo@npm:^3.0.2, svgo@npm:^3.2.0":
+ version: 3.3.2
+ resolution: "svgo@npm:3.3.2"
dependencies:
"@trysound/sax": "npm:0.2.0"
commander: "npm:^7.2.0"
- css-select: "npm:^4.1.3"
- css-tree: "npm:^1.1.3"
- csso: "npm:^4.2.0"
+ css-select: "npm:^5.1.0"
+ css-tree: "npm:^2.3.1"
+ css-what: "npm:^6.1.0"
+ csso: "npm:^5.0.5"
picocolors: "npm:^1.0.0"
- stable: "npm:^0.1.8"
bin:
- svgo: bin/svgo
- checksum: 0741f5d5cad63111a90a0ce7a1a5a9013f6d293e871b75efe39addb57f29a263e45294e485a4d2ff9cc260a5d142c8b5937b2234b4ef05efdd2706fb2d360ecc
+ svgo: ./bin/svgo
+ checksum: a6badbd3d1d6dbb177f872787699ab34320b990d12e20798ecae915f0008796a0f3c69164f1485c9def399e0ce0a5683eb4a8045e51a5e1c364bb13a0d9f79e1
+ languageName: node
+ linkType: hard
+
+"swc-loader@npm:^0.2.6":
+ version: 0.2.6
+ resolution: "swc-loader@npm:0.2.6"
+ dependencies:
+ "@swc/counter": "npm:^0.1.3"
+ peerDependencies:
+ "@swc/core": ^1.2.147
+ webpack: ">=2"
+ checksum: b06926c5cb153931589c2166aa4c7c052cc53c68758acdda480d1eb59ecddf7d74b168e33166c4f807cc9dbae4395de9d80a14ad43e265fffaa775638abf71ce
languageName: node
linkType: hard
@@ -11409,7 +11736,7 @@ __metadata:
languageName: node
linkType: hard
-"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0":
+"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1":
version: 2.2.1
resolution: "tapable@npm:2.2.1"
checksum: bc40e6efe1e554d075469cedaba69a30eeb373552aaf41caeaaa45bf56ffacc2674261b106245bd566b35d8f3329b52d838e851ee0a852120acae26e622925c9
@@ -11430,7 +11757,29 @@ __metadata:
languageName: node
linkType: hard
-"terser-webpack-plugin@npm:^5.3.7, terser-webpack-plugin@npm:^5.3.9":
+"terser-webpack-plugin@npm:^5.3.10":
+ version: 5.3.10
+ resolution: "terser-webpack-plugin@npm:5.3.10"
+ dependencies:
+ "@jridgewell/trace-mapping": "npm:^0.3.20"
+ jest-worker: "npm:^27.4.5"
+ schema-utils: "npm:^3.1.1"
+ serialize-javascript: "npm:^6.0.1"
+ terser: "npm:^5.26.0"
+ peerDependencies:
+ webpack: ^5.1.0
+ peerDependenciesMeta:
+ "@swc/core":
+ optional: true
+ esbuild:
+ optional: true
+ uglify-js:
+ optional: true
+ checksum: 66d1ed3174542560911cf96f4716aeea8d60e7caab212291705d50072b6ba844c7391442541b13c848684044042bea9ec87512b8506528c12854943da05faf91
+ languageName: node
+ linkType: hard
+
+"terser-webpack-plugin@npm:^5.3.9":
version: 5.3.9
resolution: "terser-webpack-plugin@npm:5.3.9"
dependencies:
@@ -11452,7 +11801,21 @@ __metadata:
languageName: node
linkType: hard
-"terser@npm:^5.10.0, terser@npm:^5.15.1, terser@npm:^5.16.8":
+"terser@npm:^5.10.0, terser@npm:^5.15.1, terser@npm:^5.26.0":
+ version: 5.36.0
+ resolution: "terser@npm:5.36.0"
+ dependencies:
+ "@jridgewell/source-map": "npm:^0.3.3"
+ acorn: "npm:^8.8.2"
+ commander: "npm:^2.20.0"
+ source-map-support: "npm:~0.5.20"
+ bin:
+ terser: bin/terser
+ checksum: f4ed2bead19f64789ddcfb85b7cef78f3942f967b8890c54f57d1e35bc7d547d551c6a4c32210bce6ba45b1c738314bbfac6acbc6c762a45cd171777d0c120d9
+ languageName: node
+ linkType: hard
+
+"terser@npm:^5.16.8":
version: 5.24.0
resolution: "terser@npm:5.24.0"
dependencies:
@@ -11524,13 +11887,6 @@ __metadata:
languageName: node
linkType: hard
-"tr46@npm:~0.0.3":
- version: 0.0.3
- resolution: "tr46@npm:0.0.3"
- checksum: 047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11
- languageName: node
- linkType: hard
-
"trim-lines@npm:^3.0.0":
version: 3.0.1
resolution: "trim-lines@npm:3.0.1"
@@ -11545,13 +11901,20 @@ __metadata:
languageName: node
linkType: hard
-"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.6.0":
+"tslib@npm:^2.0.3, tslib@npm:^2.6.0":
version: 2.6.2
resolution: "tslib@npm:2.6.2"
checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb
languageName: node
linkType: hard
+"type-fest@npm:^0.21.3":
+ version: 0.21.3
+ resolution: "type-fest@npm:0.21.3"
+ checksum: 902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8
+ languageName: node
+ linkType: hard
+
"type-fest@npm:^1.0.1":
version: 1.4.0
resolution: "type-fest@npm:1.4.0"
@@ -11585,17 +11948,10 @@ __metadata:
languageName: node
linkType: hard
-"ua-parser-js@npm:^1.0.35":
- version: 1.0.37
- resolution: "ua-parser-js@npm:1.0.37"
- checksum: dac8cf82a55b2e097bd2286954e01454c4cfcf23c9d9b56961ce94bda3cec5a38ca536e6e84c20a4000a9d4b4a4abcbd98ec634ccebe21be36595ea3069126e4
- languageName: node
- linkType: hard
-
-"uc.micro@npm:^1.0.1, uc.micro@npm:^1.0.5":
- version: 1.0.6
- resolution: "uc.micro@npm:1.0.6"
- checksum: 9bde2afc6f2e24b899db6caea47dae778b88862ca76688d844ef6e6121dec0679c152893a74a6cfbd2e6fde34654e6bd8424fee8e0166cdfa6c9ae5d42b8a17b
+"uc.micro@npm:^2.0.0, uc.micro@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "uc.micro@npm:2.1.0"
+ checksum: 8862eddb412dda76f15db8ad1c640ccc2f47cdf8252a4a30be908d535602c8d33f9855dfcccb8b8837855c1ce1eaa563f7fa7ebe3c98fd0794351aab9b9c55fa
languageName: node
linkType: hard
@@ -11781,17 +12137,17 @@ __metadata:
languageName: node
linkType: hard
-"update-browserslist-db@npm:^1.0.13":
- version: 1.0.13
- resolution: "update-browserslist-db@npm:1.0.13"
+"update-browserslist-db@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "update-browserslist-db@npm:1.1.1"
dependencies:
- escalade: "npm:^3.1.1"
- picocolors: "npm:^1.0.0"
+ escalade: "npm:^3.2.0"
+ picocolors: "npm:^1.1.0"
peerDependencies:
browserslist: ">= 4.21.0"
bin:
update-browserslist-db: cli.js
- checksum: e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6
+ checksum: 536a2979adda2b4be81b07e311bd2f3ad5e978690987956bc5f514130ad50cac87cd22c710b686d79731e00fbee8ef43efe5fcd72baa241045209195d43dcc80
languageName: node
linkType: hard
@@ -11843,47 +12199,21 @@ __metadata:
languageName: node
linkType: hard
-"use-composed-ref@npm:^1.3.0":
- version: 1.3.0
- resolution: "use-composed-ref@npm:1.3.0"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: e64ce52f4b18c020407636784192726807404a2552609acf7497b66a2b7070674fb5d2b950d426c4aa85f353e2bbecb02ebf9c5b865cd06797938c70bcbf5d26
- languageName: node
- linkType: hard
-
-"use-isomorphic-layout-effect@npm:^1.1.1":
- version: 1.1.2
- resolution: "use-isomorphic-layout-effect@npm:1.1.2"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0
- peerDependenciesMeta:
- "@types/react":
- optional: true
- checksum: d8deea8b85e55ac6daba237a889630bfdbf0ebf60e9e22b6a78a78c26fabe6025e04ada7abef1e444e6786227d921e648b2707db8b3564daf757264a148a6e23
- languageName: node
- linkType: hard
-
-"use-latest-callback@npm:^0.1.9":
- version: 0.1.9
- resolution: "use-latest-callback@npm:0.1.9"
+"use-latest-callback@npm:^0.2.1":
+ version: 0.2.3
+ resolution: "use-latest-callback@npm:0.2.3"
peerDependencies:
react: ">=16.8"
- checksum: 280fa1f36e6c4bcb0546d9196b45b9176fe3481aca422e587616fe10b0bec1d5d261c91c01789257d7f02064d506b2c5618c32365c58d0cc8876dc839fe1a83f
+ checksum: dc87503f6279ce2980f78e1019231ba20d7509e9d17adac05285babe4d6ba6f68c52f4ef7b5ad777cbc2af9fbaaa09d7adb664ca556da0aebab9f020022880be
languageName: node
linkType: hard
-"use-latest@npm:^1.2.1":
- version: 1.2.1
- resolution: "use-latest@npm:1.2.1"
- dependencies:
- use-isomorphic-layout-effect: "npm:^1.1.1"
+"use-sync-external-store@npm:^1.2.2":
+ version: 1.2.2
+ resolution: "use-sync-external-store@npm:1.2.2"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
- peerDependenciesMeta:
- "@types/react":
- optional: true
- checksum: 1958886fc35262d973f5cd4ce16acd6ce3a66707a72761c93abd1b5ae64e1a11efa83f68e6c8c9bf1647628037980ce59df64cba50adb36bd4071851e70527d2
+ checksum: 23b1597c10adf15b26ade9e8c318d8cc0abc9ec0ab5fc7ca7338da92e89c2536abd150a5891bf076836c352fdfa104fc7231fb48f806fd9960e0cbe03601abaf
languageName: node
linkType: hard
@@ -11969,28 +12299,13 @@ __metadata:
languageName: node
linkType: hard
-"wait-on@npm:^7.0.1":
- version: 7.2.0
- resolution: "wait-on@npm:7.2.0"
- dependencies:
- axios: "npm:^1.6.1"
- joi: "npm:^17.11.0"
- lodash: "npm:^4.17.21"
- minimist: "npm:^1.2.8"
- rxjs: "npm:^7.8.1"
- bin:
- wait-on: bin/wait-on
- checksum: 1eff2189b3e4b0975889f3e480c75ca2a0d4275072779a6329e7cae8b729620594aa044509ddd89967de6ab2162169501b67b8d9562c16cac517837ffce17337
- languageName: node
- linkType: hard
-
-"watchpack@npm:^2.4.0":
- version: 2.4.0
- resolution: "watchpack@npm:2.4.0"
+"watchpack@npm:^2.4.1":
+ version: 2.4.2
+ resolution: "watchpack@npm:2.4.2"
dependencies:
glob-to-regexp: "npm:^0.4.1"
graceful-fs: "npm:^4.1.2"
- checksum: c5e35f9fb9338d31d2141d9835643c0f49b5f9c521440bb648181059e5940d93dd8ed856aa8a33fbcdd4e121dad63c7e8c15c063cf485429cd9d427be197fe62
+ checksum: ec60a5f0e9efaeca0102fd9126346b3b2d523e01c34030d3fddf5813a7125765121ebdc2552981136dcd2c852deb1af0b39340f2fcc235f292db5399d0283577
languageName: node
linkType: hard
@@ -12010,16 +12325,9 @@ __metadata:
languageName: node
linkType: hard
-"webidl-conversions@npm:^3.0.0":
- version: 3.0.1
- resolution: "webidl-conversions@npm:3.0.1"
- checksum: 5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db
- languageName: node
- linkType: hard
-
-"webpack-bundle-analyzer@npm:^4.9.0":
- version: 4.10.1
- resolution: "webpack-bundle-analyzer@npm:4.10.1"
+"webpack-bundle-analyzer@npm:^4.10.2":
+ version: 4.10.2
+ resolution: "webpack-bundle-analyzer@npm:4.10.2"
dependencies:
"@discoveryjs/json-ext": "npm:0.5.7"
acorn: "npm:^8.0.4"
@@ -12029,20 +12337,19 @@ __metadata:
escape-string-regexp: "npm:^4.0.0"
gzip-size: "npm:^6.0.0"
html-escaper: "npm:^2.0.2"
- is-plain-object: "npm:^5.0.0"
opener: "npm:^1.5.2"
picocolors: "npm:^1.0.0"
sirv: "npm:^2.0.3"
ws: "npm:^7.3.1"
bin:
webpack-bundle-analyzer: lib/bin/analyzer.js
- checksum: 6a94c8f6aa03296fb2eb00d6ad3b27bd5c551590fd253772bc61debf3177414d42701014079d4f85c74ba1ca685ae9f0cb4063812b58c21f294d108e9908e5cd
+ checksum: 00603040e244ead15b2d92981f0559fa14216381349412a30070a7358eb3994cd61a8221d34a3b3fb8202dc3d1c5ee1fbbe94c5c52da536e5b410aa1cf279a48
languageName: node
linkType: hard
-"webpack-dev-middleware@npm:^5.3.1":
- version: 5.3.3
- resolution: "webpack-dev-middleware@npm:5.3.3"
+"webpack-dev-middleware@npm:^5.3.4":
+ version: 5.3.4
+ resolution: "webpack-dev-middleware@npm:5.3.4"
dependencies:
colorette: "npm:^2.0.10"
memfs: "npm:^3.4.3"
@@ -12051,13 +12358,13 @@ __metadata:
schema-utils: "npm:^4.0.0"
peerDependencies:
webpack: ^4.0.0 || ^5.0.0
- checksum: 378ceed430b61c0b0eccdbb55a97173aa36231bb88e20ad12bafb3d553e542708fa31f08474b9c68d4ac95174a047def9e426e193b7134be3736afa66a0d1708
+ checksum: 257df7d6bc5494d1d3cb66bba70fbdf5a6e0423e39b6420f7631aeb52435afbfbff8410a62146dcdf3d2f945c62e03193aae2ac1194a2f7d5a2523b9d194e9e1
languageName: node
linkType: hard
-"webpack-dev-server@npm:^4.15.1":
- version: 4.15.1
- resolution: "webpack-dev-server@npm:4.15.1"
+"webpack-dev-server@npm:^4.15.2":
+ version: 4.15.2
+ resolution: "webpack-dev-server@npm:4.15.2"
dependencies:
"@types/bonjour": "npm:^3.5.9"
"@types/connect-history-api-fallback": "npm:^1.3.5"
@@ -12087,7 +12394,7 @@ __metadata:
serve-index: "npm:^1.9.1"
sockjs: "npm:^0.3.24"
spdy: "npm:^4.0.2"
- webpack-dev-middleware: "npm:^5.3.1"
+ webpack-dev-middleware: "npm:^5.3.4"
ws: "npm:^8.13.0"
peerDependencies:
webpack: ^4.37.0 || ^5.0.0
@@ -12098,7 +12405,7 @@ __metadata:
optional: true
bin:
webpack-dev-server: bin/webpack-dev-server.js
- checksum: 2cf3edf556dcafdfc938e0adeac3dadf97fb959ed66b88bdd70acdb0b77b0f25be5e2d4b30cca2da8732548451418cadf00eb09e751e7674ff914fd9ab646b26
+ checksum: 625bd5b79360afcf98782c8b1fd710b180bb0e96d96b989defff550c546890010ceea82ffbecb2a0a23f7f018bc72f2dee7b3070f7b448fb0110df6657fb2904
languageName: node
linkType: hard
@@ -12113,61 +12420,75 @@ __metadata:
languageName: node
linkType: hard
-"webpack-sources@npm:^3.2.2, webpack-sources@npm:^3.2.3":
+"webpack-merge@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "webpack-merge@npm:6.0.1"
+ dependencies:
+ clone-deep: "npm:^4.0.1"
+ flat: "npm:^5.0.2"
+ wildcard: "npm:^2.0.1"
+ checksum: bf1429567858b353641801b8a2696ca0aac270fc8c55d4de8a7b586fe07d27fdcfc83099a98ab47e6162383db8dd63bb8cc25b1beb2ec82150422eec843b0dc0
+ languageName: node
+ linkType: hard
+
+"webpack-sources@npm:^3.2.3":
version: 3.2.3
resolution: "webpack-sources@npm:3.2.3"
checksum: 2ef63d77c4fad39de4a6db17323d75eb92897b32674e97d76f0a1e87c003882fc038571266ad0ef581ac734cbe20952912aaa26155f1905e96ce251adbb1eb4e
languageName: node
linkType: hard
-"webpack@npm:^5.88.1":
- version: 5.89.0
- resolution: "webpack@npm:5.89.0"
+"webpack@npm:^5.88.1, webpack@npm:^5.95.0":
+ version: 5.96.1
+ resolution: "webpack@npm:5.96.1"
dependencies:
- "@types/eslint-scope": "npm:^3.7.3"
- "@types/estree": "npm:^1.0.0"
- "@webassemblyjs/ast": "npm:^1.11.5"
- "@webassemblyjs/wasm-edit": "npm:^1.11.5"
- "@webassemblyjs/wasm-parser": "npm:^1.11.5"
- acorn: "npm:^8.7.1"
- acorn-import-assertions: "npm:^1.9.0"
- browserslist: "npm:^4.14.5"
+ "@types/eslint-scope": "npm:^3.7.7"
+ "@types/estree": "npm:^1.0.6"
+ "@webassemblyjs/ast": "npm:^1.12.1"
+ "@webassemblyjs/wasm-edit": "npm:^1.12.1"
+ "@webassemblyjs/wasm-parser": "npm:^1.12.1"
+ acorn: "npm:^8.14.0"
+ browserslist: "npm:^4.24.0"
chrome-trace-event: "npm:^1.0.2"
- enhanced-resolve: "npm:^5.15.0"
+ enhanced-resolve: "npm:^5.17.1"
es-module-lexer: "npm:^1.2.1"
eslint-scope: "npm:5.1.1"
events: "npm:^3.2.0"
glob-to-regexp: "npm:^0.4.1"
- graceful-fs: "npm:^4.2.9"
+ graceful-fs: "npm:^4.2.11"
json-parse-even-better-errors: "npm:^2.3.1"
loader-runner: "npm:^4.2.0"
mime-types: "npm:^2.1.27"
neo-async: "npm:^2.6.2"
schema-utils: "npm:^3.2.0"
tapable: "npm:^2.1.1"
- terser-webpack-plugin: "npm:^5.3.7"
- watchpack: "npm:^2.4.0"
+ terser-webpack-plugin: "npm:^5.3.10"
+ watchpack: "npm:^2.4.1"
webpack-sources: "npm:^3.2.3"
peerDependenciesMeta:
webpack-cli:
optional: true
bin:
webpack: bin/webpack.js
- checksum: 2562bf48788d651634fb7db6a5378c2fe3fce7f66831af38468da3944bd98756d68efea94a6909593993fb57b2d14cf802cbef2c83c6ef0047f7f606d59bec50
+ checksum: ae6052fde9a546f79f14987b65823ba4024c6642a8489339ecfee7a351dff93325842aad453295bbdc6b65fb1690e4ef07529db63aa84ece55c7869e991a0039
languageName: node
linkType: hard
-"webpackbar@npm:^5.0.2":
- version: 5.0.2
- resolution: "webpackbar@npm:5.0.2"
+"webpackbar@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "webpackbar@npm:6.0.1"
dependencies:
- chalk: "npm:^4.1.0"
- consola: "npm:^2.15.3"
+ ansi-escapes: "npm:^4.3.2"
+ chalk: "npm:^4.1.2"
+ consola: "npm:^3.2.3"
+ figures: "npm:^3.2.0"
+ markdown-table: "npm:^2.0.0"
pretty-time: "npm:^1.1.0"
- std-env: "npm:^3.0.1"
+ std-env: "npm:^3.7.0"
+ wrap-ansi: "npm:^7.0.0"
peerDependencies:
webpack: 3 || 4 || 5
- checksum: 336568a6ed1c1ad743c8d20a5cab5875a7ebe1e96181f49ae0a1a897f1a59d1661d837574a25d8ba9dfa4f2f705bd46ca0cd037ff60286ff70fb8d9db2b0c123
+ checksum: 8dfa2c55f8122f729c7efd515a2b50fb752c0d0cb27ec2ecdbc70d90a86d5f69f466c9c5d01004f71b500dafba957ecd4413fca196a98cf99a39b705f98cae97
languageName: node
linkType: hard
@@ -12189,16 +12510,6 @@ __metadata:
languageName: node
linkType: hard
-"whatwg-url@npm:^5.0.0":
- version: 5.0.0
- resolution: "whatwg-url@npm:5.0.0"
- dependencies:
- tr46: "npm:~0.0.3"
- webidl-conversions: "npm:^3.0.0"
- checksum: 1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5
- languageName: node
- linkType: hard
-
"which@npm:^1.3.1":
version: 1.3.1
resolution: "which@npm:1.3.1"
@@ -12241,14 +12552,14 @@ __metadata:
languageName: node
linkType: hard
-"wildcard@npm:^2.0.0":
+"wildcard@npm:^2.0.0, wildcard@npm:^2.0.1":
version: 2.0.1
resolution: "wildcard@npm:2.0.1"
checksum: 08f70cd97dd9a20aea280847a1fe8148e17cae7d231640e41eb26d2388697cbe65b67fd9e68715251c39b080c5ae4f76d71a9a69fa101d897273efdfb1b58bf7
languageName: node
linkType: hard
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
version: 7.0.0
resolution: "wrap-ansi@npm:7.0.0"
dependencies:
@@ -12351,14 +12662,7 @@ __metadata:
languageName: node
linkType: hard
-"yaml@npm:2.3.4":
- version: 2.3.4
- resolution: "yaml@npm:2.3.4"
- checksum: cf03b68f8fef5e8516b0f0b54edaf2459f1648317fc6210391cf606d247e678b449382f4bd01f77392538429e306c7cba8ff46ff6b37cac4de9a76aff33bd9e1
- languageName: node
- linkType: hard
-
-"yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2":
+"yaml@npm:^1.7.2":
version: 1.10.2
resolution: "yaml@npm:1.10.2"
checksum: 5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f