mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-12 22:51:18 +08:00
Compare commits
33 Commits
@react-nav
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee435be3a | ||
|
|
016e7920df | ||
|
|
26ba019155 | ||
|
|
97772affa3 | ||
|
|
67f6950c14 | ||
|
|
fe6d20c10e | ||
|
|
7d74bd73a7 | ||
|
|
b46c433f1e | ||
|
|
7e71ee6c47 | ||
|
|
1287a784e6 | ||
|
|
56f7df5384 | ||
|
|
5996bbbce2 | ||
|
|
c3ba72df65 | ||
|
|
be40244214 | ||
|
|
7388e6d9bc | ||
|
|
00e70da0d4 | ||
|
|
70f4fe2ffa | ||
|
|
e639748b23 | ||
|
|
324ea7181d | ||
|
|
9d3731c2df | ||
|
|
baf8ff77d5 | ||
|
|
b4d7b0ee86 | ||
|
|
a184ce24b3 | ||
|
|
80cdc88588 | ||
|
|
b91c9b05ff | ||
|
|
29cdd886a0 | ||
|
|
1d40279db1 | ||
|
|
cde44a5785 | ||
|
|
aa77f0618b | ||
|
|
a5520d7ef1 | ||
|
|
0c1a061a04 | ||
|
|
d5f5521d5d | ||
|
|
c90bff08d5 |
@@ -75,9 +75,13 @@ jobs:
|
||||
- run:
|
||||
name: Build example for web
|
||||
command: yarn example expo build:web --no-pwa
|
||||
# Yarn does not execute the postinstall scripts if the package is in the cache
|
||||
- run:
|
||||
name: Install browsers
|
||||
command: yarn playwright install
|
||||
- run:
|
||||
name: Run integration tests
|
||||
command: yarn example test --maxWorkers=2
|
||||
command: yarn example test:e2e
|
||||
|
||||
build-packages:
|
||||
executor: default
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": "satya164",
|
||||
"plugins": ["simple-import-sort"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "16"
|
||||
@@ -23,6 +24,13 @@
|
||||
"node": true
|
||||
},
|
||||
"rules": {
|
||||
"react/no-unused-prop-types": "off"
|
||||
}
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error"
|
||||
},
|
||||
"overrides": [{
|
||||
"files":["example/e2e/tests/*.ts"],
|
||||
"rules": {
|
||||
"jest/*": 0
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
.yarnrc
2
.yarnrc
@@ -2,4 +2,4 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
yarn-path ".yarn/releases/yarn-1.18.0.js"
|
||||
yarn-path ".yarn/releases/yarn-1.22.10.cjs"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'react-native-gesture-handler';
|
||||
|
||||
import { Assets } from '@react-navigation/elements';
|
||||
import { registerRootComponent } from 'expo';
|
||||
import { Asset } from 'expo-asset';
|
||||
import { Assets } from '@react-navigation/elements';
|
||||
|
||||
import App from './src/index';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*/
|
||||
package com.reactnavigation;
|
||||
package org.reactnavigation.example;
|
||||
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
@@ -66,4 +66,4 @@ public class ReactNativeFlipper {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import { page } from '../config/setup-playwright';
|
||||
|
||||
beforeEach(async () => {
|
||||
await page.click('[data-testid=LinkComponent]');
|
||||
});
|
||||
|
||||
const getPageInfo = async () => ({
|
||||
url: await page.evaluate(() => location.pathname + location.search),
|
||||
title: await page.evaluate(() => document.title),
|
||||
heading: (await page.accessibility.snapshot())?.children?.find(
|
||||
(it) => it.role === 'heading'
|
||||
)?.name,
|
||||
});
|
||||
|
||||
it('loads the article page', async () => {
|
||||
const { url, title, heading } = await getPageInfo();
|
||||
|
||||
expect(url).toBe('/link-component/article/gandalf');
|
||||
expect(title).toBe('Article by Gandalf - React Navigation Example');
|
||||
expect(heading).toBe('Article by Gandalf');
|
||||
});
|
||||
|
||||
it('goes to the album page and goes back', async () => {
|
||||
await page.click('[href="/link-component/music"]');
|
||||
|
||||
{
|
||||
const { url, title, heading } = await getPageInfo();
|
||||
|
||||
expect(url).toBe('/link-component/music');
|
||||
expect(title).toBe('Albums - React Navigation Example');
|
||||
expect(heading).toBe('Albums');
|
||||
}
|
||||
|
||||
await page.click('[aria-label="Article by Gandalf, back"]');
|
||||
await page.waitForNavigation();
|
||||
|
||||
{
|
||||
const { url, title, heading } = await getPageInfo();
|
||||
|
||||
expect(url).toBe('/link-component/article/gandalf');
|
||||
expect(title).toBe('Article by Gandalf - React Navigation Example');
|
||||
expect(heading).toBe('Article by Gandalf');
|
||||
}
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
/* eslint-env jest */
|
||||
|
||||
import { chromium, Browser, BrowserContext, Page } from 'playwright';
|
||||
|
||||
let browser: Browser;
|
||||
let context: BrowserContext;
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async () => {
|
||||
browser = await chromium.launch();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
context = await browser.newContext();
|
||||
page = await context.newPage();
|
||||
|
||||
await page.goto('http://localhost:3579');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
export { browser, context, page };
|
||||
28
example/e2e/playwright.config.ts
Normal file
28
example/e2e/playwright.config.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
import path from 'path';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: path.join(__dirname, 'tests'),
|
||||
globalSetup: require.resolve('./config/setup-server.ts'),
|
||||
globalTeardown: require.resolve('./config/teardown-server.ts'),
|
||||
workers: 1,
|
||||
reporter: 'list',
|
||||
projects: [
|
||||
{
|
||||
name: 'Chromium',
|
||||
use: { browserName: 'chromium' },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Firefox',
|
||||
use: { browserName: 'firefox' },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'WebKit',
|
||||
use: { browserName: 'webkit' },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
43
example/e2e/tests/Link.test.ts
Normal file
43
example/e2e/tests/Link.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
|
||||
import { expect, it } from './baseFixture';
|
||||
|
||||
it.beforeEach(async ({ page }) => {
|
||||
await page.click('[data-testid=LinkComponent]');
|
||||
});
|
||||
|
||||
const waitAndAssertPageHeading = async (
|
||||
page: Page,
|
||||
expectedHeading: string
|
||||
) => {
|
||||
await page.waitForSelector(`text=${expectedHeading}`);
|
||||
const heading = (await page.accessibility.snapshot())?.children?.find(
|
||||
(it) => it.role === 'heading'
|
||||
)?.name;
|
||||
expect(heading).toBe(expectedHeading);
|
||||
};
|
||||
|
||||
it('loads the article page', async ({ page }) => {
|
||||
await page.waitForURL('**/link-component/article/gandalf');
|
||||
expect(await page.title()).toBe(
|
||||
'Article by Gandalf - React Navigation Example'
|
||||
);
|
||||
await waitAndAssertPageHeading(page, 'Article by Gandalf');
|
||||
});
|
||||
|
||||
it('goes to the album page and goes back', async ({ page }) => {
|
||||
await page.click('[href="/link-component/music"]');
|
||||
|
||||
await page.waitForURL('**/link-component/music');
|
||||
expect(await page.title()).toBe('Albums - React Navigation Example');
|
||||
await waitAndAssertPageHeading(page, 'Albums');
|
||||
|
||||
await page.click('[aria-label="Article by Gandalf, back"]');
|
||||
await page.waitForNavigation();
|
||||
|
||||
await page.waitForURL('**/link-component/article/gandalf');
|
||||
expect(await page.title()).toBe(
|
||||
'Article by Gandalf - React Navigation Example'
|
||||
);
|
||||
await waitAndAssertPageHeading(page, 'Article by Gandalf');
|
||||
});
|
||||
11
example/e2e/tests/baseFixture.ts
Normal file
11
example/e2e/tests/baseFixture.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { test as baseTest } from '@playwright/test';
|
||||
|
||||
const test = baseTest.extend({
|
||||
page: async ({ page }, use) => {
|
||||
await page.goto('http://localhost:3579');
|
||||
await use(page);
|
||||
},
|
||||
});
|
||||
|
||||
export const it = test;
|
||||
export const expect = test.expect;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { page } from '../config/setup-playwright';
|
||||
import { expect, it } from './baseFixture';
|
||||
|
||||
it('loads the example app', async () => {
|
||||
it('loads the example app', async ({ page }) => {
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
|
||||
expect(
|
||||
@@ -1,5 +1,6 @@
|
||||
import fetch from 'node-fetch';
|
||||
import { expect, test as it } from '@playwright/test';
|
||||
import cheerio from 'cheerio';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const server = 'http://localhost:3275';
|
||||
|
||||
@@ -23,15 +23,15 @@ PODS:
|
||||
- UMImageLoaderInterface
|
||||
- EXKeepAwake (9.1.2):
|
||||
- UMCore
|
||||
- EXPermissions (12.0.0):
|
||||
- EXPermissions (12.0.1):
|
||||
- UMCore
|
||||
- UMPermissionsInterface
|
||||
- EXSplashScreen (0.10.0):
|
||||
- EXSplashScreen (0.10.2):
|
||||
- React-Core
|
||||
- UMCore
|
||||
- EXStructuredHeaders (1.0.1):
|
||||
- UMCore
|
||||
- EXUpdates (0.5.4):
|
||||
- EXUpdates (0.5.5):
|
||||
- EXStructuredHeaders
|
||||
- React-Core
|
||||
- UMCore
|
||||
@@ -271,9 +271,9 @@ PODS:
|
||||
- React
|
||||
- react-native-flipper (0.80.0):
|
||||
- React-Core
|
||||
- react-native-safe-area-context (3.2.0):
|
||||
- react-native-pager-view (5.1.10):
|
||||
- React-Core
|
||||
- react-native-viewpager (5.0.12):
|
||||
- react-native-safe-area-context (3.2.0):
|
||||
- React-Core
|
||||
- React-RCTActionSheet (0.63.4):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.63.4)
|
||||
@@ -335,13 +335,13 @@ PODS:
|
||||
- React-Core (= 0.63.4)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- RNCAsyncStorage (1.15.1):
|
||||
- RNCAsyncStorage (1.15.5):
|
||||
- React-Core
|
||||
- RNCMaskedView (0.2.4):
|
||||
- React-Core
|
||||
- RNGestureHandler (1.10.3):
|
||||
- React-Core
|
||||
- RNReanimated (2.1.0):
|
||||
- RNReanimated (2.2.0):
|
||||
- DoubleConversion
|
||||
- FBLazyVector
|
||||
- FBReactNativeSpec
|
||||
@@ -370,8 +370,9 @@ PODS:
|
||||
- React-RCTVibration
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- RNScreens (3.0.0):
|
||||
- RNScreens (3.3.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNVectorIcons (8.1.0):
|
||||
- React-Core
|
||||
- UMAppLoader (2.1.0)
|
||||
@@ -451,8 +452,8 @@ DEPENDENCIES:
|
||||
- React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- react-native-appearance (from `../../node_modules/react-native-appearance`)
|
||||
- react-native-flipper (from `../../node_modules/react-native-flipper`)
|
||||
- react-native-pager-view (from `../../node_modules/react-native-pager-view`)
|
||||
- react-native-safe-area-context (from `../../node_modules/react-native-safe-area-context`)
|
||||
- react-native-viewpager (from `../node_modules/react-native-pager-view`)
|
||||
- React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
- React-RCTBlob (from `../../node_modules/react-native/Libraries/Blob`)
|
||||
@@ -464,7 +465,7 @@ DEPENDENCIES:
|
||||
- React-RCTVibration (from `../../node_modules/react-native/Libraries/Vibration`)
|
||||
- ReactCommon/turbomodule/core (from `../../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../../node_modules/@react-native-async-storage/async-storage`)"
|
||||
- "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)"
|
||||
- "RNCMaskedView (from `../../node_modules/@react-native-masked-view/masked-view`)"
|
||||
- RNGestureHandler (from `../../node_modules/react-native-gesture-handler`)
|
||||
- RNReanimated (from `../../node_modules/react-native-reanimated`)
|
||||
- RNScreens (from `../../node_modules/react-native-screens`)
|
||||
@@ -558,10 +559,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../../node_modules/react-native-appearance"
|
||||
react-native-flipper:
|
||||
:path: "../../node_modules/react-native-flipper"
|
||||
react-native-pager-view:
|
||||
:path: "../../node_modules/react-native-pager-view"
|
||||
react-native-safe-area-context:
|
||||
:path: "../../node_modules/react-native-safe-area-context"
|
||||
react-native-viewpager:
|
||||
:path: "../node_modules/react-native-pager-view"
|
||||
React-RCTActionSheet:
|
||||
:path: "../../node_modules/react-native/Libraries/ActionSheetIOS"
|
||||
React-RCTAnimation:
|
||||
@@ -585,7 +586,7 @@ EXTERNAL SOURCES:
|
||||
RNCAsyncStorage:
|
||||
:path: "../../node_modules/@react-native-async-storage/async-storage"
|
||||
RNCMaskedView:
|
||||
:path: "../node_modules/@react-native-masked-view/masked-view"
|
||||
:path: "../../node_modules/@react-native-masked-view/masked-view"
|
||||
RNGestureHandler:
|
||||
:path: "../../node_modules/react-native-gesture-handler"
|
||||
RNReanimated:
|
||||
@@ -635,10 +636,10 @@ SPEC CHECKSUMS:
|
||||
EXFont: d6fb79f9863120f0d0b26b0c2d1453bc9511e9df
|
||||
EXImageLoader: da941c9399e01ec28f2d5b270bdd21f2c8ca596c
|
||||
EXKeepAwake: d4e4a3ed8c1c4fd940dd62fc5a8be2a190371fd4
|
||||
EXPermissions: 67ff17d3c12ea06066492dde4242f8047658fd62
|
||||
EXSplashScreen: 9d79ea338b7bb2ee94df51723870bac70b408d44
|
||||
EXPermissions: 8f8c1c05580c4e02d4ee2c8dd74bfe173ff6a723
|
||||
EXSplashScreen: a9baaf4fa866003884c90ba049f18760d6a8ce39
|
||||
EXStructuredHeaders: be834496a4d9fd0069cd12ec1cc57b31c6d3b256
|
||||
EXUpdates: e191b83e00d3e7ebfd7db3986806ceca09b7b322
|
||||
EXUpdates: efe0e8c514dcff06a8fd0b63be6019a6365fb9c7
|
||||
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
|
||||
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
|
||||
Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021
|
||||
@@ -664,8 +665,8 @@ SPEC CHECKSUMS:
|
||||
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
|
||||
react-native-appearance: 0f0e5fc2fcef70e03d48c8fe6b00b9158c2ba8aa
|
||||
react-native-flipper: 5a9d5959364fca6a8a9658d941343774cb197857
|
||||
react-native-pager-view: 967d50ce0f1b72e434a2d9f3b739ddbf7d5bbf83
|
||||
react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79
|
||||
react-native-viewpager: 98a850d1c7ac6263122d82618a77062a5f427073
|
||||
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
|
||||
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
|
||||
React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
|
||||
@@ -676,11 +677,11 @@ SPEC CHECKSUMS:
|
||||
React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c
|
||||
React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
|
||||
ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
|
||||
RNCAsyncStorage: 08719e311ab90492c2dafd6d6fb7ffb396493638
|
||||
RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
|
||||
RNCMaskedView: fc29d354a40316a990e8fb46391f08aea829c3aa
|
||||
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
|
||||
RNReanimated: 70f662b5232dd5d19ccff581e919a54ea73df51c
|
||||
RNScreens: e8e8dd0588b5da0ab57dcca76ab9b2d8987757e0
|
||||
RNReanimated: d9da990fc90123f4ffbfdda93d00fc15174863a8
|
||||
RNScreens: bf59f17fbf001f1025243eeed5f19419d3c11ef2
|
||||
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
|
||||
UMAppLoader: fe2708bb0ac5cd70052bc207d06aa3b7e72b9e97
|
||||
UMBarCodeScannerInterface: 79f92bea5f7af39b381a4c82298105ceb537408a
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
testRegex: '/__integration_tests__/.*\\.(test|spec)\\.(js|tsx?)$',
|
||||
globalSetup: './e2e/config/setup-server.tsx',
|
||||
globalTeardown: './e2e/config/teardown-server.tsx',
|
||||
setupFilesAfterEnv: ['./e2e/config/setup-playwright.tsx'],
|
||||
};
|
||||
@@ -11,65 +11,63 @@
|
||||
"ios": "react-native run-ios",
|
||||
"preios": "pod-install",
|
||||
"server": "nodemon -e '.js,.ts,.tsx' --exec \"babel-node -i '/node_modules[/\\](?react-native)/' -x '.web.tsx,.web.ts,.web.js,.tsx,.ts,.js' --config-file ./server/babel.config.js server\"",
|
||||
"test": "jest"
|
||||
"test:e2e": "playwright test --config=e2e/playwright.config.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^12.0.0",
|
||||
"@react-native-async-storage/async-storage": "^1.13.0",
|
||||
"@expo/vector-icons": "^12.0.5",
|
||||
"@react-native-async-storage/async-storage": "^1.15.5",
|
||||
"@react-native-masked-view/masked-view": "~0.2.4",
|
||||
"color": "^3.1.3",
|
||||
"expo": "^41.0.1",
|
||||
"expo-asset": "~8.3.1",
|
||||
"expo-asset": "~8.3.2",
|
||||
"expo-blur": "~9.0.3",
|
||||
"expo-linking": "~2.2.3",
|
||||
"expo-splash-screen": "~0.10.0",
|
||||
"expo-splash-screen": "~0.10.2",
|
||||
"expo-status-bar": "~1.0.4",
|
||||
"expo-updates": "~0.5.4",
|
||||
"expo-updates": "~0.5.5",
|
||||
"koa": "^2.13.0",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
"react-native": "~0.63.4",
|
||||
"react-native-appearance": "~0.3.3",
|
||||
"react-native-gesture-handler": "~1.10.2",
|
||||
"react-native-pager-view": "~5.0.12",
|
||||
"react-native-paper": "^4.7.2",
|
||||
"react-native-reanimated": "~2.1.0",
|
||||
"react-native-pager-view": "~5.1.10",
|
||||
"react-native-paper": "^4.9.1",
|
||||
"react-native-reanimated": "~2.2.0",
|
||||
"react-native-safe-area-context": "~3.2.0",
|
||||
"react-native-screens": "~3.0.0",
|
||||
"react-native-screens": "~3.3.0",
|
||||
"react-native-tab-view": "^3.0.1",
|
||||
"react-native-unimodules": "~0.13.1",
|
||||
"react-native-unimodules": "~0.13.3",
|
||||
"react-native-vector-icons": "^8.1.0",
|
||||
"react-native-web": "~0.15.0"
|
||||
"react-native-web": "~0.16.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/node": "^7.13.13",
|
||||
"@expo/webpack-config": "~0.12.63",
|
||||
"@types/cheerio": "^0.22.28",
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/node": "^7.14.2",
|
||||
"@expo/webpack-config": "~0.12.76",
|
||||
"@playwright/test": "^1.12.2",
|
||||
"@types/cheerio": "^0.22.29",
|
||||
"@types/jest-dev-server": "^4.2.0",
|
||||
"@types/koa": "^2.13.1",
|
||||
"@types/koa": "^2.13.3",
|
||||
"@types/mock-require": "^2.0.0",
|
||||
"@types/node-fetch": "^2.5.9",
|
||||
"@types/react": "~16.9.35",
|
||||
"@types/react-dom": "~16.9.8",
|
||||
"@types/react-native": "~0.63.2",
|
||||
"babel-jest": "~25.2.6",
|
||||
"@types/node-fetch": "^2.5.10",
|
||||
"@types/react": "~17.0.9",
|
||||
"@types/react-dom": "~17.0.6",
|
||||
"@types/react-native": "~0.64.9",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-plugin-module-resolver": "^4.0.0",
|
||||
"babel-preset-expo": "8.3.0",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"expo-cli": "^4.4.4",
|
||||
"jest": "^26.6.3",
|
||||
"jest-dev-server": "^4.4.0",
|
||||
"cheerio": "^1.0.0-rc.9",
|
||||
"expo-cli": "^4.5.2",
|
||||
"jest-dev-server": "^5.0.3",
|
||||
"mock-require": "^3.0.3",
|
||||
"mock-require-assets": "^0.0.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"nodemon": "^2.0.6",
|
||||
"playwright": "^1.11.0",
|
||||
"pod-install": "^0.1.19",
|
||||
"pod-install": "^0.1.23",
|
||||
"react-native-flipper": "~0.80.0",
|
||||
"react-test-renderer": "~16.13.1",
|
||||
"serve": "^11.3.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "^4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,9 @@ const alias = Object.fromEntries(
|
||||
fs
|
||||
.readdirSync(packages)
|
||||
.filter((name) => !name.startsWith('.'))
|
||||
.map((name) => [
|
||||
`@react-navigation/${name}`,
|
||||
path.resolve(
|
||||
packages,
|
||||
name,
|
||||
require(`../../packages/${name}/package.json`).source
|
||||
),
|
||||
])
|
||||
.map((name) => [name, require(`../../packages/${name}/package.json`)])
|
||||
.filter(([, pak]) => pak.source != null)
|
||||
.map(([name, pak]) => [pak.name, path.resolve(packages, name, pak.source)])
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import './resolve-hooks';
|
||||
|
||||
import { ServerContainer, ServerContainerRef } from '@react-navigation/native';
|
||||
import Koa from 'koa';
|
||||
import * as React from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { AppRegistry } from 'react-native-web';
|
||||
import { ServerContainer, ServerContainerRef } from '@react-navigation/native';
|
||||
|
||||
import App from '../src/index';
|
||||
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { View, TextInput, ActivityIndicator, StyleSheet } from 'react-native';
|
||||
import { Title, Button } from 'react-native-paper';
|
||||
import { useTheme, ParamListBase } from '@react-navigation/native';
|
||||
import { HeaderBackButton } from '@react-navigation/elements';
|
||||
import { ParamListBase, useTheme } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import { HeaderBackButton } from '@react-navigation/elements';
|
||||
import * as React from 'react';
|
||||
import { ActivityIndicator, StyleSheet, TextInput, View } from 'react-native';
|
||||
import { Button, Title } from 'react-native-paper';
|
||||
|
||||
type AuthStackParams = {
|
||||
Splash: undefined;
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
import * as React from 'react';
|
||||
import { ScrollView, StyleSheet } from 'react-native';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { BlurView } from 'expo-blur';
|
||||
import {
|
||||
getFocusedRouteNameFromRoute,
|
||||
ParamListBase,
|
||||
NavigatorScreenParams,
|
||||
} from '@react-navigation/native';
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
import {
|
||||
createBottomTabNavigator,
|
||||
useBottomTabBarHeight,
|
||||
} from '@react-navigation/bottom-tabs';
|
||||
import { HeaderBackButton } from '@react-navigation/elements';
|
||||
import {
|
||||
getFocusedRouteNameFromRoute,
|
||||
NavigatorScreenParams,
|
||||
ParamListBase,
|
||||
} from '@react-navigation/native';
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
import { BlurView } from 'expo-blur';
|
||||
import * as React from 'react';
|
||||
import { ScrollView, StyleSheet } from 'react-native';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Contacts from '../Shared/Contacts';
|
||||
import Chat from '../Shared/Chat';
|
||||
import Contacts from '../Shared/Contacts';
|
||||
import SimpleStackScreen, { SimpleStackParams } from './SimpleStack';
|
||||
|
||||
const getTabBarIcon = (name: string) => ({
|
||||
color,
|
||||
size,
|
||||
}: {
|
||||
color: string;
|
||||
size: number;
|
||||
}) => <MaterialCommunityIcons name={name} color={color} size={size} />;
|
||||
const getTabBarIcon =
|
||||
(name: string) =>
|
||||
({ color, size }: { color: string; size: number }) =>
|
||||
<MaterialCommunityIcons name={name} color={color} size={size} />;
|
||||
|
||||
type BottomTabParams = {
|
||||
TabStack: NavigatorScreenParams<SimpleStackParams>;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
import { Title, Button } from 'react-native-paper';
|
||||
import Feather from 'react-native-vector-icons/Feather';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import * as React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Button, Title } from 'react-native-paper';
|
||||
import Feather from 'react-native-vector-icons/Feather';
|
||||
|
||||
type BottomTabParams = {
|
||||
[key: string]: undefined;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import * as React from 'react';
|
||||
import { View, StyleSheet, ScrollView, Platform } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import {
|
||||
Link,
|
||||
StackActions,
|
||||
ParamListBase,
|
||||
StackActions,
|
||||
useLinkProps,
|
||||
} from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
|
||||
type SimpleStackParams = {
|
||||
Article: { author: string };
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import {
|
||||
createDrawerNavigator,
|
||||
DrawerContent,
|
||||
DrawerContentComponentProps,
|
||||
DrawerScreenProps,
|
||||
} from '@react-navigation/drawer';
|
||||
import {
|
||||
ParamListBase,
|
||||
useNavigation,
|
||||
useTheme,
|
||||
} from '@react-navigation/native';
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
import * as React from 'react';
|
||||
import { Dimensions, ScaledSize } from 'react-native';
|
||||
import { Appbar } from 'react-native-paper';
|
||||
import {
|
||||
useTheme,
|
||||
useNavigation,
|
||||
ParamListBase,
|
||||
} from '@react-navigation/native';
|
||||
import {
|
||||
createDrawerNavigator,
|
||||
DrawerScreenProps,
|
||||
DrawerContent,
|
||||
DrawerContentComponentProps,
|
||||
} from '@react-navigation/drawer';
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
import Article from '../Shared/Article';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
import NewsFeed from '../Shared/NewsFeed';
|
||||
|
||||
type DrawerParams = {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
|
||||
import type { NavigatorScreenParams } from '@react-navigation/native';
|
||||
import * as React from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import type { NavigatorScreenParams } from '@react-navigation/native';
|
||||
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Contacts from '../Shared/Contacts';
|
||||
import Chat from '../Shared/Chat';
|
||||
import Contacts from '../Shared/Contacts';
|
||||
import SimpleStackScreen, { SimpleStackParams } from './SimpleStack';
|
||||
|
||||
type MaterialBottomTabParams = {
|
||||
@@ -14,7 +15,8 @@ type MaterialBottomTabParams = {
|
||||
TabChat: undefined;
|
||||
};
|
||||
|
||||
const MaterialBottomTabs = createMaterialBottomTabNavigator<MaterialBottomTabParams>();
|
||||
const MaterialBottomTabs =
|
||||
createMaterialBottomTabNavigator<MaterialBottomTabParams>();
|
||||
|
||||
export default function MaterialBottomTabsScreen() {
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as React from 'react';
|
||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
||||
import * as React from 'react';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Contacts from '../Shared/Contacts';
|
||||
import Chat from '../Shared/Chat';
|
||||
import Contacts from '../Shared/Contacts';
|
||||
|
||||
type MaterialTopTabParams = {
|
||||
Albums: undefined;
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import * as React from 'react';
|
||||
import { View, Platform, StyleSheet, ScrollView } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
HeaderStyleInterpolators,
|
||||
StackScreenProps,
|
||||
TransitionPresets,
|
||||
HeaderStyleInterpolators,
|
||||
} from '@react-navigation/stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
import NewsFeed from '../Shared/NewsFeed';
|
||||
|
||||
export type SimpleStackParams = {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { View, StyleSheet, ScrollView, Platform } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
|
||||
type MixedStackParams = {
|
||||
Article: { author: string };
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { View, StyleSheet, ScrollView, Platform } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
|
||||
type ModalStackParams = {
|
||||
Article: { author: string };
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import { View, Platform, StyleSheet, ScrollView } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import {
|
||||
createNativeStackNavigator,
|
||||
NativeStackScreenProps,
|
||||
} from '@react-navigation/native-stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
import NewsFeed from '../Shared/NewsFeed';
|
||||
|
||||
export type NativeStackParams = {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { View, Platform, StyleSheet, ScrollView, Alert } from 'react-native';
|
||||
import { Appbar, Button } from 'react-native-paper';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import {
|
||||
createNativeStackNavigator,
|
||||
NativeStackScreenProps,
|
||||
} from '@react-navigation/native-stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Alert, Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Appbar, Button } from 'react-native-paper';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
import NewsFeed from '../Shared/NewsFeed';
|
||||
|
||||
export type NativeStackParams = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
import * as React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import type { StackScreenProps } from '@react-navigation/stack';
|
||||
|
||||
const NotFoundScreen = ({
|
||||
route,
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Alert,
|
||||
View,
|
||||
TextInput,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import {
|
||||
useTheme,
|
||||
CommonActions,
|
||||
ParamListBase,
|
||||
NavigationAction,
|
||||
ParamListBase,
|
||||
useTheme,
|
||||
} from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Alert,
|
||||
Platform,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import Article from '../Shared/Article';
|
||||
|
||||
type PreventRemoveParams = {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import { View, Platform, StyleSheet, ScrollView } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import type { ParamListBase } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackNavigationOptions,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import { Platform, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
import NewsFeed from '../Shared/NewsFeed';
|
||||
|
||||
export type SimpleStackParams = {
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Animated,
|
||||
View,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
Alert,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { Button, Appbar } from 'react-native-paper';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { useTheme, ParamListBase } from '@react-navigation/native';
|
||||
import { HeaderBackground, useHeaderHeight } from '@react-navigation/elements';
|
||||
import { ParamListBase, useTheme } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
Header,
|
||||
StackHeaderProps,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import { HeaderBackground, useHeaderHeight } from '@react-navigation/elements';
|
||||
import BlurView from '../Shared/BlurView';
|
||||
import Article from '../Shared/Article';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Alert,
|
||||
Animated,
|
||||
Platform,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Appbar, Button } from 'react-native-paper';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
|
||||
import Albums from '../Shared/Albums';
|
||||
import Article from '../Shared/Article';
|
||||
import BlurView from '../Shared/BlurView';
|
||||
|
||||
type SimpleStackParams = {
|
||||
Article: { author: string };
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
View,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
Platform,
|
||||
Pressable,
|
||||
Animated,
|
||||
} from 'react-native';
|
||||
import { Button, Paragraph } from 'react-native-paper';
|
||||
import { ParamListBase, useTheme } from '@react-navigation/native';
|
||||
import {
|
||||
createStackNavigator,
|
||||
StackScreenProps,
|
||||
useCardAnimation,
|
||||
} from '@react-navigation/stack';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Animated,
|
||||
Platform,
|
||||
Pressable,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Button, Paragraph } from 'react-native-paper';
|
||||
|
||||
import Article from '../Shared/Article';
|
||||
import NewsFeed from '../Shared/NewsFeed';
|
||||
|
||||
type TransparentStackParams = {
|
||||
Article: { author: string };
|
||||
NewsFeed: undefined;
|
||||
Dialog: undefined;
|
||||
};
|
||||
|
||||
@@ -37,6 +40,13 @@ const ArticleScreen = ({
|
||||
>
|
||||
Show Dialog
|
||||
</Button>
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={() => navigation.push('NewsFeed')}
|
||||
style={styles.button}
|
||||
>
|
||||
Push NewsFeed
|
||||
</Button>
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={() => navigation.goBack()}
|
||||
@@ -53,6 +63,32 @@ const ArticleScreen = ({
|
||||
);
|
||||
};
|
||||
|
||||
const NewsFeedScreen = ({
|
||||
navigation,
|
||||
}: StackScreenProps<TransparentStackParams, 'NewsFeed'>) => {
|
||||
return (
|
||||
<ScrollView>
|
||||
<View style={styles.buttons}>
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={() => navigation.push('Dialog')}
|
||||
style={styles.button}
|
||||
>
|
||||
Show Dialog
|
||||
</Button>
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={() => navigation.goBack()}
|
||||
style={styles.button}
|
||||
>
|
||||
Go back
|
||||
</Button>
|
||||
</View>
|
||||
<NewsFeed scrollEnabled={scrollEnabled} />
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const DialogScreen = ({
|
||||
navigation,
|
||||
}: StackScreenProps<TransparentStackParams>) => {
|
||||
@@ -116,6 +152,11 @@ export default function TransparentStackScreen({ navigation }: Props) {
|
||||
component={ArticleScreen}
|
||||
initialParams={{ author: 'Gandalf' }}
|
||||
/>
|
||||
<TransparentStack.Screen
|
||||
name="NewsFeed"
|
||||
component={NewsFeedScreen}
|
||||
options={{ presentation: 'modal' }}
|
||||
/>
|
||||
<TransparentStack.Screen
|
||||
name="Dialog"
|
||||
component={DialogScreen}
|
||||
@@ -131,6 +172,7 @@ export default function TransparentStackScreen({ navigation }: Props) {
|
||||
const styles = StyleSheet.create({
|
||||
buttons: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
padding: 8,
|
||||
},
|
||||
button: {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
|
||||
import { useScrollToTop } from '@react-navigation/native';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
View,
|
||||
Image,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
ScrollViewProps,
|
||||
Dimensions,
|
||||
Image,
|
||||
Platform,
|
||||
ScaledSize,
|
||||
ScrollView,
|
||||
ScrollViewProps,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { useScrollToTop } from '@react-navigation/native';
|
||||
|
||||
const COVERS = [
|
||||
require('../../assets/album-art-01.jpg'),
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useScrollToTop, useTheme } from '@react-navigation/native';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
Image,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
ScrollViewProps,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextProps,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { useScrollToTop, useTheme } from '@react-navigation/native';
|
||||
|
||||
type Props = Partial<ScrollViewProps> & {
|
||||
date?: string;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
View,
|
||||
Image,
|
||||
Text,
|
||||
TextInput,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
ScrollViewProps,
|
||||
} from 'react-native';
|
||||
import { useScrollToTop, useTheme } from '@react-navigation/native';
|
||||
import Color from 'color';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Image,
|
||||
ScrollView,
|
||||
ScrollViewProps,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
const MESSAGES = [
|
||||
'okay',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { View, Text, FlatList, StyleSheet } from 'react-native';
|
||||
import { useScrollToTop, useTheme } from '@react-navigation/native';
|
||||
import * as React from 'react';
|
||||
import { FlatList, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
type Item = { name: string; number: number };
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { useScrollToTop, useTheme } from '@react-navigation/native';
|
||||
import Color from 'color';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
View,
|
||||
TextInput,
|
||||
Image,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
ScrollViewProps,
|
||||
StyleSheet,
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { useScrollToTop, useTheme } from '@react-navigation/native';
|
||||
import {
|
||||
Card,
|
||||
Text,
|
||||
Avatar,
|
||||
Subheading,
|
||||
IconButton,
|
||||
Card,
|
||||
Divider,
|
||||
IconButton,
|
||||
Subheading,
|
||||
Text,
|
||||
} from 'react-native-paper';
|
||||
import Color from 'color';
|
||||
|
||||
type Props = Partial<ScrollViewProps> & {
|
||||
date?: number;
|
||||
|
||||
@@ -1,65 +1,69 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
ScrollView,
|
||||
Platform,
|
||||
StatusBar,
|
||||
I18nManager,
|
||||
Dimensions,
|
||||
ScaledSize,
|
||||
Linking,
|
||||
LogBox,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
import {
|
||||
Provider as PaperProvider,
|
||||
DefaultTheme as PaperLightTheme,
|
||||
DarkTheme as PaperDarkTheme,
|
||||
List,
|
||||
Divider,
|
||||
Text,
|
||||
} from 'react-native-paper';
|
||||
import { createURL } from 'expo-linking';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import {
|
||||
useFlipper,
|
||||
useReduxDevToolsExtension,
|
||||
} from '@react-navigation/devtools';
|
||||
import {
|
||||
createDrawerNavigator,
|
||||
DrawerScreenProps,
|
||||
} from '@react-navigation/drawer';
|
||||
import {
|
||||
CompositeScreenProps,
|
||||
DarkTheme,
|
||||
DefaultTheme,
|
||||
InitialState,
|
||||
NavigationContainer,
|
||||
DefaultTheme,
|
||||
DarkTheme,
|
||||
NavigatorScreenParams,
|
||||
PathConfigMap,
|
||||
useNavigationContainerRef,
|
||||
NavigatorScreenParams,
|
||||
} from '@react-navigation/native';
|
||||
import { createDrawerNavigator } from '@react-navigation/drawer';
|
||||
import {
|
||||
createStackNavigator,
|
||||
HeaderStyleInterpolators,
|
||||
StackNavigationProp,
|
||||
StackScreenProps,
|
||||
} from '@react-navigation/stack';
|
||||
import { createURL } from 'expo-linking';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
useReduxDevToolsExtension,
|
||||
useFlipper,
|
||||
} from '@react-navigation/devtools';
|
||||
Dimensions,
|
||||
I18nManager,
|
||||
Linking,
|
||||
LogBox,
|
||||
Platform,
|
||||
ScaledSize,
|
||||
ScrollView,
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
import {
|
||||
DarkTheme as PaperDarkTheme,
|
||||
DefaultTheme as PaperLightTheme,
|
||||
Divider,
|
||||
List,
|
||||
Provider as PaperProvider,
|
||||
Text,
|
||||
} from 'react-native-paper';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
|
||||
import { restartApp } from './Restart';
|
||||
import SettingsItem from './Shared/SettingsItem';
|
||||
import NativeStack from './Screens/NativeStack';
|
||||
import SimpleStack from './Screens/SimpleStack';
|
||||
import ModalStack from './Screens/ModalStack';
|
||||
import MixedStack from './Screens/MixedStack';
|
||||
import MixedHeaderMode from './Screens/MixedHeaderMode';
|
||||
import StackTransparent from './Screens/StackTransparent';
|
||||
import StackHeaderCustomization from './Screens/StackHeaderCustomization';
|
||||
import NativeStackHeaderCustomization from './Screens/NativeStackHeaderCustomization';
|
||||
import BottomTabs from './Screens/BottomTabs';
|
||||
import MaterialTopTabsScreen from './Screens/MaterialTopTabs';
|
||||
import MaterialBottomTabs from './Screens/MaterialBottomTabs';
|
||||
import NotFound from './Screens/NotFound';
|
||||
import DynamicTabs from './Screens/DynamicTabs';
|
||||
import MasterDetail from './Screens/MasterDetail';
|
||||
import AuthFlow from './Screens/AuthFlow';
|
||||
import PreventRemove from './Screens/PreventRemove';
|
||||
import BottomTabs from './Screens/BottomTabs';
|
||||
import DynamicTabs from './Screens/DynamicTabs';
|
||||
import LinkComponent from './Screens/LinkComponent';
|
||||
import MasterDetail from './Screens/MasterDetail';
|
||||
import MaterialBottomTabs from './Screens/MaterialBottomTabs';
|
||||
import MaterialTopTabsScreen from './Screens/MaterialTopTabs';
|
||||
import MixedHeaderMode from './Screens/MixedHeaderMode';
|
||||
import MixedStack from './Screens/MixedStack';
|
||||
import ModalStack from './Screens/ModalStack';
|
||||
import NativeStack from './Screens/NativeStack';
|
||||
import NativeStackHeaderCustomization from './Screens/NativeStackHeaderCustomization';
|
||||
import NotFound from './Screens/NotFound';
|
||||
import PreventRemove from './Screens/PreventRemove';
|
||||
import SimpleStack from './Screens/SimpleStack';
|
||||
import StackHeaderCustomization from './Screens/StackHeaderCustomization';
|
||||
import StackTransparent from './Screens/StackTransparent';
|
||||
import SettingsItem from './Shared/SettingsItem';
|
||||
|
||||
if (Platform.OS !== 'web') {
|
||||
LogBox.ignoreLogs(['Require cycle:']);
|
||||
@@ -151,9 +155,8 @@ export default function App() {
|
||||
const [theme, setTheme] = React.useState(DefaultTheme);
|
||||
|
||||
const [isReady, setIsReady] = React.useState(Platform.OS === 'web');
|
||||
const [initialState, setInitialState] = React.useState<
|
||||
InitialState | undefined
|
||||
>();
|
||||
const [initialState, setInitialState] =
|
||||
React.useState<InitialState | undefined>();
|
||||
|
||||
React.useEffect(() => {
|
||||
const restoreState = async () => {
|
||||
@@ -333,9 +336,10 @@ export default function App() {
|
||||
>
|
||||
{({
|
||||
navigation,
|
||||
}: {
|
||||
navigation: StackNavigationProp<RootStackParamList>;
|
||||
}) => (
|
||||
}: CompositeScreenProps<
|
||||
DrawerScreenProps<RootDrawerParamList, 'Examples'>,
|
||||
StackScreenProps<RootStackParamList>
|
||||
>) => (
|
||||
<ScrollView
|
||||
style={{ backgroundColor: theme.colors.background }}
|
||||
>
|
||||
|
||||
@@ -8,8 +8,6 @@ const packages = path.resolve(__dirname, '..', 'packages');
|
||||
module.exports = async function (env, argv) {
|
||||
const config = await createExpoWebpackConfigAsync(env, argv);
|
||||
|
||||
config.context = path.resolve(__dirname, '..');
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.(js|ts|tsx)$/,
|
||||
include: /(packages|example)\/.+/,
|
||||
@@ -27,11 +25,13 @@ module.exports = async function (env, argv) {
|
||||
fs.readdirSync(packages)
|
||||
.filter((name) => !name.startsWith('.'))
|
||||
.forEach((name) => {
|
||||
config.resolve.alias[`@react-navigation/${name}`] = path.resolve(
|
||||
packages,
|
||||
name,
|
||||
require(`../packages/${name}/package.json`).source
|
||||
);
|
||||
const pak = require(`../packages/${name}/package.json`);
|
||||
|
||||
if (pak.source == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
config.resolve.alias[pak.name] = path.resolve(packages, name, pak.source);
|
||||
});
|
||||
|
||||
return config;
|
||||
|
||||
21
package.json
21
package.json
@@ -29,20 +29,24 @@
|
||||
"release": "lerna publish",
|
||||
"example": "yarn --cwd example"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-native-web": "~0.16.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/config-conventional": "^12.1.1",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@commitlint/config-conventional": "^12.1.4",
|
||||
"@types/jest": "^26.0.23",
|
||||
"babel-jest": "^26.6.3",
|
||||
"codecov": "^3.8.1",
|
||||
"commitlint": "^12.1.1",
|
||||
"eslint": "^7.23.0",
|
||||
"codecov": "^3.8.2",
|
||||
"commitlint": "^12.1.4",
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-config-satya164": "^3.1.10",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"husky": "^4.3.6",
|
||||
"jest": "^26.6.3",
|
||||
"lerna": "^4.0.0",
|
||||
"metro-react-native-babel-preset": "^0.65.2",
|
||||
"prettier": "^2.2.1",
|
||||
"typescript": "^4.2.3"
|
||||
"metro-react-native-babel-preset": "^0.66.0",
|
||||
"prettier": "^2.3.0",
|
||||
"typescript": "^4.3.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"react": "~16.13.1",
|
||||
@@ -66,6 +70,7 @@
|
||||
"preset": "react-native"
|
||||
},
|
||||
"prettier": {
|
||||
"quoteProps": "consistent",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
|
||||
@@ -3,6 +3,65 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [6.0.0-next.19](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.18...@react-navigation/bottom-tabs@6.0.0-next.19) (2021-06-10)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.18](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.17...@react-navigation/bottom-tabs@6.0.0-next.18) (2021-06-01)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.17](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.16...@react-navigation/bottom-tabs@6.0.0-next.17) (2021-05-29)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.16](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.15...@react-navigation/bottom-tabs@6.0.0-next.16) (2021-05-29)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.15](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.14...@react-navigation/bottom-tabs@6.0.0-next.15) (2021-05-27)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.14](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.13...@react-navigation/bottom-tabs@6.0.0-next.14) (2021-05-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add screenListeners prop on navigators similar to screenOptions ([cde44a5](https://github.com/react-navigation/react-navigation/commit/cde44a5785444a121aa08f94af9f8fe4fc89910a))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.13](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.12...@react-navigation/bottom-tabs@6.0.0-next.13) (2021-05-25)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.12](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.11...@react-navigation/bottom-tabs@6.0.0-next.12) (2021-05-23)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-navigation/bottom-tabs",
|
||||
"description": "Bottom tab navigator following iOS design guidelines",
|
||||
"version": "6.0.0-next.12",
|
||||
"version": "6.0.0-next.19",
|
||||
"keywords": [
|
||||
"react-native-component",
|
||||
"react-component",
|
||||
@@ -36,23 +36,23 @@
|
||||
"clean": "del lib"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-navigation/elements": "^1.0.0-next.11",
|
||||
"@react-navigation/elements": "^1.0.0-next.18",
|
||||
"color": "^3.1.3",
|
||||
"warn-once": "^0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@react-navigation/native": "^6.0.0-next.9",
|
||||
"@react-navigation/native": "^6.0.0-next.14",
|
||||
"@testing-library/react-native": "^7.2.0",
|
||||
"@types/color": "^3.0.1",
|
||||
"@types/react": "^16.9.53",
|
||||
"@types/react-native": "~0.64.4",
|
||||
"@types/react": "^17.0.9",
|
||||
"@types/react-native": "~0.64.9",
|
||||
"del-cli": "^3.0.1",
|
||||
"react": "~16.13.1",
|
||||
"react-native": "~0.63.4",
|
||||
"react-native-builder-bob": "^0.18.1",
|
||||
"react-native-safe-area-context": "~3.2.0",
|
||||
"react-native-screens": "~3.0.0",
|
||||
"typescript": "^4.2.3"
|
||||
"react-native-screens": "~3.3.0",
|
||||
"typescript": "^4.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^6.0.0",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { View, Text, Button } from 'react-native';
|
||||
import { render, fireEvent } from '@testing-library/react-native';
|
||||
import { NavigationContainer, ParamListBase } from '@react-navigation/native';
|
||||
import { createBottomTabNavigator, BottomTabScreenProps } from '../index';
|
||||
import { fireEvent, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
import { Button, Text, View } from 'react-native';
|
||||
|
||||
import { BottomTabScreenProps, createBottomTabNavigator } from '../index';
|
||||
|
||||
it('renders a bottom tab navigator with screens', async () => {
|
||||
const Test = ({ route, navigation }: BottomTabScreenProps<ParamListBase>) => (
|
||||
|
||||
@@ -6,23 +6,22 @@ export { default as createBottomTabNavigator } from './navigators/createBottomTa
|
||||
/**
|
||||
* Views
|
||||
*/
|
||||
export { default as BottomTabView } from './views/BottomTabView';
|
||||
export { default as BottomTabBar } from './views/BottomTabBar';
|
||||
export { default as BottomTabView } from './views/BottomTabView';
|
||||
|
||||
/**
|
||||
* Utilities
|
||||
*/
|
||||
export { default as BottomTabBarHeightContext } from './utils/BottomTabBarHeightContext';
|
||||
|
||||
export { default as useBottomTabBarHeight } from './utils/useBottomTabBarHeight';
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
export type {
|
||||
BottomTabBarButtonProps,
|
||||
BottomTabBarProps,
|
||||
BottomTabNavigationOptions,
|
||||
BottomTabNavigationProp,
|
||||
BottomTabScreenProps,
|
||||
BottomTabBarProps,
|
||||
BottomTabBarButtonProps,
|
||||
} from './types';
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
import * as React from 'react';
|
||||
import warnOnce from 'warn-once';
|
||||
import {
|
||||
useNavigationBuilder,
|
||||
createNavigatorFactory,
|
||||
DefaultNavigatorOptions,
|
||||
ParamListBase,
|
||||
TabActionHelpers,
|
||||
TabNavigationState,
|
||||
TabRouter,
|
||||
TabRouterOptions,
|
||||
TabNavigationState,
|
||||
TabActionHelpers,
|
||||
ParamListBase,
|
||||
useNavigationBuilder,
|
||||
} from '@react-navigation/native';
|
||||
import BottomTabView from '../views/BottomTabView';
|
||||
import * as React from 'react';
|
||||
import warnOnce from 'warn-once';
|
||||
|
||||
import type {
|
||||
BottomTabNavigationConfig,
|
||||
BottomTabNavigationOptions,
|
||||
BottomTabNavigationEventMap,
|
||||
BottomTabNavigationOptions,
|
||||
} from '../types';
|
||||
import BottomTabView from '../views/BottomTabView';
|
||||
|
||||
type Props = DefaultNavigatorOptions<BottomTabNavigationOptions> &
|
||||
type Props = DefaultNavigatorOptions<
|
||||
ParamListBase,
|
||||
TabNavigationState<ParamListBase>,
|
||||
BottomTabNavigationOptions,
|
||||
BottomTabNavigationEventMap
|
||||
> &
|
||||
TabRouterOptions &
|
||||
BottomTabNavigationConfig;
|
||||
|
||||
@@ -25,6 +31,7 @@ function BottomTabNavigator({
|
||||
initialRouteName,
|
||||
backBehavior,
|
||||
children,
|
||||
screenListeners,
|
||||
screenOptions,
|
||||
sceneContainerStyle,
|
||||
// @ts-expect-error: lazy is deprecated
|
||||
@@ -70,24 +77,21 @@ function BottomTabNavigator({
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
state,
|
||||
descriptors,
|
||||
navigation,
|
||||
NavigationContent,
|
||||
} = useNavigationBuilder<
|
||||
TabNavigationState<ParamListBase>,
|
||||
TabRouterOptions,
|
||||
TabActionHelpers<ParamListBase>,
|
||||
BottomTabNavigationOptions,
|
||||
BottomTabNavigationEventMap
|
||||
>(TabRouter, {
|
||||
initialRouteName,
|
||||
backBehavior,
|
||||
children,
|
||||
screenOptions,
|
||||
defaultScreenOptions,
|
||||
});
|
||||
const { state, descriptors, navigation, NavigationContent } =
|
||||
useNavigationBuilder<
|
||||
TabNavigationState<ParamListBase>,
|
||||
TabRouterOptions,
|
||||
TabActionHelpers<ParamListBase>,
|
||||
BottomTabNavigationOptions,
|
||||
BottomTabNavigationEventMap
|
||||
>(TabRouter, {
|
||||
initialRouteName,
|
||||
backBehavior,
|
||||
children,
|
||||
screenListeners,
|
||||
screenOptions,
|
||||
defaultScreenOptions,
|
||||
});
|
||||
|
||||
return (
|
||||
<NavigationContent>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import type * as React from 'react';
|
||||
import type {
|
||||
Animated,
|
||||
TouchableWithoutFeedbackProps,
|
||||
StyleProp,
|
||||
TextStyle,
|
||||
ViewStyle,
|
||||
GestureResponderEvent,
|
||||
} from 'react-native';
|
||||
import type { HeaderOptions } from '@react-navigation/elements';
|
||||
import type {
|
||||
Descriptor,
|
||||
NavigationHelpers,
|
||||
NavigationProp,
|
||||
ParamListBase,
|
||||
Descriptor,
|
||||
TabNavigationState,
|
||||
TabActionHelpers,
|
||||
RouteProp,
|
||||
TabActionHelpers,
|
||||
TabNavigationState,
|
||||
} from '@react-navigation/native';
|
||||
import type * as React from 'react';
|
||||
import type {
|
||||
Animated,
|
||||
GestureResponderEvent,
|
||||
StyleProp,
|
||||
TextStyle,
|
||||
TouchableWithoutFeedbackProps,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import type { EdgeInsets } from 'react-native-safe-area-context';
|
||||
import type { HeaderOptions } from '@react-navigation/elements';
|
||||
|
||||
export type Layout = { width: number; height: number };
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import BottomTabBarHeightContext from './BottomTabBarHeightContext';
|
||||
|
||||
export default function useFloatingBottomTabBarHeight() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { Keyboard, Platform, EmitterSubscription } from 'react-native';
|
||||
import { EmitterSubscription, Keyboard, Platform } from 'react-native';
|
||||
|
||||
export default function useIsKeyboardShown() {
|
||||
const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { Animated, StyleSheet, StyleProp, TextStyle } from 'react-native';
|
||||
import color from 'color';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
import color from 'color';
|
||||
import * as React from 'react';
|
||||
import { Animated, StyleProp, StyleSheet, TextStyle } from 'react-native';
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Animated,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
LayoutChangeEvent,
|
||||
StyleProp,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import { MissingIcon } from '@react-navigation/elements';
|
||||
import {
|
||||
CommonActions,
|
||||
NavigationContext,
|
||||
NavigationRouteContext,
|
||||
TabNavigationState,
|
||||
ParamListBase,
|
||||
CommonActions,
|
||||
useTheme,
|
||||
TabNavigationState,
|
||||
useLinkBuilder,
|
||||
useTheme,
|
||||
} from '@react-navigation/native';
|
||||
import { MissingIcon } from '@react-navigation/elements';
|
||||
import React from 'react';
|
||||
import {
|
||||
Animated,
|
||||
LayoutChangeEvent,
|
||||
Platform,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
View,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import { EdgeInsets, useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||
|
||||
import BottomTabItem from './BottomTabItem';
|
||||
import type { BottomTabBarProps, BottomTabDescriptorMap } from '../types';
|
||||
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
|
||||
import useIsKeyboardShown from '../utils/useIsKeyboardShown';
|
||||
import type { BottomTabBarProps, BottomTabDescriptorMap } from '../types';
|
||||
import BottomTabItem from './BottomTabItem';
|
||||
|
||||
type Props = BottomTabBarProps & {
|
||||
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
|
||||
@@ -48,9 +48,8 @@ const shouldUseHorizontalLabels = ({
|
||||
layout,
|
||||
dimensions,
|
||||
}: Options) => {
|
||||
const { tabBarLabelPosition, tabBarAdaptive = true } = descriptors[
|
||||
state.routes[state.index].key
|
||||
].options;
|
||||
const { tabBarLabelPosition, tabBarAdaptive = true } =
|
||||
descriptors[state.routes[state.index].key].options;
|
||||
|
||||
if (tabBarLabelPosition) {
|
||||
return tabBarLabelPosition === 'beside-icon';
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Text,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
StyleProp,
|
||||
ViewStyle,
|
||||
TextStyle,
|
||||
GestureResponderEvent,
|
||||
} from 'react-native';
|
||||
import { Link, Route, useTheme } from '@react-navigation/native';
|
||||
import Color from 'color';
|
||||
import React from 'react';
|
||||
import {
|
||||
GestureResponderEvent,
|
||||
Platform,
|
||||
Pressable,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextStyle,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
|
||||
import TabBarIcon from './TabBarIcon';
|
||||
import type { BottomTabBarButtonProps, LabelPosition } from '../types';
|
||||
import TabBarIcon from './TabBarIcon';
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import * as React from 'react';
|
||||
import { StyleSheet, Platform } from 'react-native';
|
||||
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
|
||||
import {
|
||||
getHeaderTitle,
|
||||
Header,
|
||||
SafeAreaProviderCompat,
|
||||
Screen,
|
||||
} from '@react-navigation/elements';
|
||||
import type {
|
||||
ParamListBase,
|
||||
TabNavigationState,
|
||||
} from '@react-navigation/native';
|
||||
import {
|
||||
Header,
|
||||
Screen,
|
||||
SafeAreaProviderCompat,
|
||||
getHeaderTitle,
|
||||
} from '@react-navigation/elements';
|
||||
import { MaybeScreenContainer, MaybeScreen } from './ScreenFallback';
|
||||
import BottomTabBar, { getTabBarHeight } from './BottomTabBar';
|
||||
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
|
||||
import BottomTabBarHeightContext from '../utils/BottomTabBarHeightContext';
|
||||
import * as React from 'react';
|
||||
import { Platform, StyleSheet } from 'react-native';
|
||||
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
|
||||
|
||||
import type {
|
||||
BottomTabNavigationConfig,
|
||||
BottomTabDescriptorMap,
|
||||
BottomTabNavigationHelpers,
|
||||
BottomTabBarProps,
|
||||
BottomTabDescriptorMap,
|
||||
BottomTabHeaderProps,
|
||||
BottomTabNavigationConfig,
|
||||
BottomTabNavigationHelpers,
|
||||
BottomTabNavigationProp,
|
||||
} from '../types';
|
||||
import BottomTabBarHeightCallbackContext from '../utils/BottomTabBarHeightCallbackContext';
|
||||
import BottomTabBarHeightContext from '../utils/BottomTabBarHeightContext';
|
||||
import BottomTabBar, { getTabBarHeight } from './BottomTabBar';
|
||||
import { MaybeScreen, MaybeScreenContainer } from './ScreenFallback';
|
||||
|
||||
type Props = BottomTabNavigationConfig & {
|
||||
state: TabNavigationState<ParamListBase>;
|
||||
@@ -136,7 +137,8 @@ export default function BottomTabView(props: Props) {
|
||||
header={header({
|
||||
layout: dimensions,
|
||||
route: descriptor.route,
|
||||
navigation: descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
||||
navigation:
|
||||
descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
||||
options: descriptor.options,
|
||||
})}
|
||||
style={sceneContainerStyle}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ResourceSavingView } from '@react-navigation/elements';
|
||||
import * as React from 'react';
|
||||
import { StyleProp, View, ViewProps, ViewStyle } from 'react-native';
|
||||
import { ResourceSavingView } from '@react-navigation/elements';
|
||||
|
||||
type Props = {
|
||||
visible: boolean;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { Route } from '@react-navigation/native';
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
StyleSheet,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
TextStyle,
|
||||
View,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import type { Route } from '@react-navigation/native';
|
||||
|
||||
import Badge from './Badge';
|
||||
|
||||
type Props = {
|
||||
@@ -27,6 +28,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export default function TabBarIcon({
|
||||
route: _,
|
||||
horizontal,
|
||||
badge,
|
||||
badgeStyle,
|
||||
|
||||
@@ -3,6 +3,59 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [6.0.0-next.14](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.13...@react-navigation/core@6.0.0-next.14) (2021-06-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* show stack trace in the flipper plugin ([97772af](https://github.com/react-navigation/react-navigation/commit/97772affa3c8f26489f0bdbfb6872ef4377b8ed1))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.13](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.12...@react-navigation/core@6.0.0-next.13) (2021-05-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* validate property names in linking config ([324ea71](https://github.com/react-navigation/react-navigation/commit/324ea7181db6b743f512854be267cc9d65975b6f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.12](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.11...@react-navigation/core@6.0.0-next.12) (2021-05-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* try to fix [#9631](https://github.com/react-navigation/react-navigation/issues/9631) ([b4d7b0e](https://github.com/react-navigation/react-navigation/commit/b4d7b0ee86c09419a18357867a0a25bb90d960c0))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.11](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.10...@react-navigation/core@6.0.0-next.11) (2021-05-27)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/core
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.10](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.9...@react-navigation/core@6.0.0-next.10) (2021-05-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add screenListeners prop on navigators similar to screenOptions ([cde44a5](https://github.com/react-navigation/react-navigation/commit/cde44a5785444a121aa08f94af9f8fe4fc89910a))
|
||||
* expose container ref in useNavigation ([1d40279](https://github.com/react-navigation/react-navigation/commit/1d40279db18ab2aed12517ed3ca6af6d509477d2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [6.0.0-next.9](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.8...@react-navigation/core@6.0.0-next.9) (2021-05-23)
|
||||
|
||||
**Note:** Version bump only for package @react-navigation/core
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-navigation/core",
|
||||
"description": "Core utilities for building navigators",
|
||||
"version": "6.0.0-next.9",
|
||||
"version": "6.0.0-next.14",
|
||||
"keywords": [
|
||||
"react",
|
||||
"react-native",
|
||||
@@ -35,22 +35,22 @@
|
||||
"clean": "del lib"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-navigation/routers": "^6.0.0-next.3",
|
||||
"@react-navigation/routers": "^6.0.0-next.5",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"nanoid": "^3.1.22",
|
||||
"nanoid": "^3.1.23",
|
||||
"query-string": "^7.0.0",
|
||||
"react-is": "^16.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react-native": "^7.2.0",
|
||||
"@types/react": "^16.9.53",
|
||||
"@types/react-is": "^16.7.1",
|
||||
"@types/react": "^17.0.9",
|
||||
"@types/react-is": "^17.0.0",
|
||||
"del-cli": "^3.0.1",
|
||||
"immer": "^9.0.1",
|
||||
"immer": "^9.0.2",
|
||||
"react": "~16.13.1",
|
||||
"react-native-builder-bob": "^0.18.1",
|
||||
"react-test-renderer": "~16.13.1",
|
||||
"typescript": "^4.2.3"
|
||||
"typescript": "^4.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
|
||||
@@ -1,59 +1,42 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
CommonActions,
|
||||
Route,
|
||||
NavigationState,
|
||||
InitialState,
|
||||
PartialState,
|
||||
NavigationAction,
|
||||
NavigationState,
|
||||
ParamListBase,
|
||||
PartialState,
|
||||
Route,
|
||||
} from '@react-navigation/routers';
|
||||
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
||||
import UnhandledActionContext from './UnhandledActionContext';
|
||||
import NavigationBuilderContext from './NavigationBuilderContext';
|
||||
import NavigationStateContext from './NavigationStateContext';
|
||||
import NavigationRouteContext from './NavigationRouteContext';
|
||||
import NavigationContext from './NavigationContext';
|
||||
import { ScheduleUpdateContext } from './useScheduleUpdate';
|
||||
import useChildListeners from './useChildListeners';
|
||||
import useKeyedChildListeners from './useKeyedChildListeners';
|
||||
import useOptionsGetters from './useOptionsGetters';
|
||||
import useEventEmitter from './useEventEmitter';
|
||||
import useSyncState from './useSyncState';
|
||||
import checkSerializable from './checkSerializable';
|
||||
import * as React from 'react';
|
||||
|
||||
import checkDuplicateRouteNames from './checkDuplicateRouteNames';
|
||||
import findFocusedRoute from './findFocusedRoute';
|
||||
import checkSerializable from './checkSerializable';
|
||||
import { NOT_INITIALIZED_ERROR } from './createNavigationContainerRef';
|
||||
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
||||
import findFocusedRoute from './findFocusedRoute';
|
||||
import NavigationBuilderContext from './NavigationBuilderContext';
|
||||
import NavigationContainerRefContext from './NavigationContainerRefContext';
|
||||
import NavigationContext from './NavigationContext';
|
||||
import NavigationRouteContext from './NavigationRouteContext';
|
||||
import NavigationStateContext from './NavigationStateContext';
|
||||
import type {
|
||||
NavigationContainerEventMap,
|
||||
NavigationContainerRef,
|
||||
NavigationContainerProps,
|
||||
NavigationContainerRef,
|
||||
} from './types';
|
||||
import UnhandledActionContext from './UnhandledActionContext';
|
||||
import useChildListeners from './useChildListeners';
|
||||
import useEventEmitter from './useEventEmitter';
|
||||
import useKeyedChildListeners from './useKeyedChildListeners';
|
||||
import useOptionsGetters from './useOptionsGetters';
|
||||
import { ScheduleUpdateContext } from './useScheduleUpdate';
|
||||
import useSyncState from './useSyncState';
|
||||
|
||||
type State = NavigationState | PartialState<NavigationState> | undefined;
|
||||
|
||||
const serializableWarnings: string[] = [];
|
||||
const duplicateNameWarnings: string[] = [];
|
||||
|
||||
try {
|
||||
/**
|
||||
* Migration instructions for removal of devtools from core
|
||||
*/
|
||||
Object.defineProperty(
|
||||
global,
|
||||
'REACT_NAVIGATION_REDUX_DEVTOOLS_EXTENSION_INTEGRATION_ENABLED',
|
||||
{
|
||||
set(_) {
|
||||
console.warn(
|
||||
"Redux devtools extension integration can be enabled with the '@react-navigation/devtools' package. For more details, see https://reactnavigation.org/docs/devtools"
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove `key` and `routeNames` from the state objects recursively to get partial state.
|
||||
*
|
||||
@@ -112,15 +95,10 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
);
|
||||
}
|
||||
|
||||
const [
|
||||
state,
|
||||
getState,
|
||||
setState,
|
||||
scheduleUpdate,
|
||||
flushUpdates,
|
||||
] = useSyncState<State>(() =>
|
||||
getPartialState(initialState == null ? undefined : initialState)
|
||||
);
|
||||
const [state, getState, setState, scheduleUpdate, flushUpdates] =
|
||||
useSyncState<State>(() =>
|
||||
getPartialState(initialState == null ? undefined : initialState)
|
||||
);
|
||||
|
||||
const isFirstMountRef = React.useRef<boolean>(true);
|
||||
|
||||
@@ -136,17 +114,22 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
|
||||
const { keyedListeners, addKeyedListener } = useKeyedChildListeners();
|
||||
|
||||
const dispatch = (
|
||||
action: NavigationAction | ((state: NavigationState) => NavigationAction)
|
||||
) => {
|
||||
if (listeners.focus[0] == null) {
|
||||
console.error(NOT_INITIALIZED_ERROR);
|
||||
} else {
|
||||
listeners.focus[0]((navigation) => navigation.dispatch(action));
|
||||
}
|
||||
};
|
||||
const dispatch = React.useCallback(
|
||||
(
|
||||
action:
|
||||
| NavigationAction
|
||||
| ((state: NavigationState) => NavigationAction)
|
||||
) => {
|
||||
if (listeners.focus[0] == null) {
|
||||
console.error(NOT_INITIALIZED_ERROR);
|
||||
} else {
|
||||
listeners.focus[0]((navigation) => navigation.dispatch(action));
|
||||
}
|
||||
},
|
||||
[listeners.focus]
|
||||
);
|
||||
|
||||
const canGoBack = () => {
|
||||
const canGoBack = React.useCallback(() => {
|
||||
if (listeners.focus[0] == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -160,7 +143,7 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}, [listeners.focus]);
|
||||
|
||||
const resetRoot = React.useCallback(
|
||||
(state?: PartialState<NavigationState> | NavigationState) => {
|
||||
@@ -200,28 +183,45 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
|
||||
const { addOptionsGetter, getCurrentOptions } = useOptionsGetters({});
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
...Object.keys(CommonActions).reduce<any>((acc, name) => {
|
||||
acc[name] = (...args: any[]) =>
|
||||
// @ts-expect-error: this is ok
|
||||
dispatch(CommonActions[name](...args));
|
||||
return acc;
|
||||
}, {}),
|
||||
...emitter.create('root'),
|
||||
resetRoot,
|
||||
dispatch,
|
||||
canGoBack,
|
||||
getRootState,
|
||||
getState: () => state,
|
||||
getParent: () => undefined,
|
||||
getCurrentRoute,
|
||||
getCurrentOptions,
|
||||
isReady: () => listeners.focus[0] != null,
|
||||
}));
|
||||
const navigation: NavigationContainerRef<ParamListBase> = React.useMemo(
|
||||
() => ({
|
||||
...Object.keys(CommonActions).reduce<any>((acc, name) => {
|
||||
acc[name] = (...args: any[]) =>
|
||||
// @ts-expect-error: this is ok
|
||||
dispatch(CommonActions[name](...args));
|
||||
return acc;
|
||||
}, {}),
|
||||
...emitter.create('root'),
|
||||
resetRoot,
|
||||
dispatch,
|
||||
canGoBack,
|
||||
getRootState,
|
||||
getState: () => stateRef.current,
|
||||
getParent: () => undefined,
|
||||
getCurrentRoute,
|
||||
getCurrentOptions,
|
||||
isReady: () => listeners.focus[0] != null,
|
||||
}),
|
||||
[
|
||||
canGoBack,
|
||||
dispatch,
|
||||
emitter,
|
||||
getCurrentOptions,
|
||||
getCurrentRoute,
|
||||
getRootState,
|
||||
listeners.focus,
|
||||
resetRoot,
|
||||
]
|
||||
);
|
||||
|
||||
React.useImperativeHandle(ref, () => navigation, [navigation]);
|
||||
|
||||
const onDispatchAction = React.useCallback(
|
||||
(action: NavigationAction, noop: boolean) => {
|
||||
emitter.emit({ type: '__unsafe_action__', data: { action, noop } });
|
||||
emitter.emit({
|
||||
type: '__unsafe_action__',
|
||||
data: { action, noop, stack: stackRef.current },
|
||||
});
|
||||
},
|
||||
[emitter]
|
||||
);
|
||||
@@ -244,12 +244,15 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
[emitter]
|
||||
);
|
||||
|
||||
const stackRef = React.useRef<string | undefined>();
|
||||
|
||||
const builderContext = React.useMemo(
|
||||
() => ({
|
||||
addListener,
|
||||
addKeyedListener,
|
||||
onDispatchAction,
|
||||
onOptionsChange,
|
||||
stackRef,
|
||||
}),
|
||||
[addListener, addKeyedListener, onDispatchAction, onOptionsChange]
|
||||
);
|
||||
@@ -285,10 +288,12 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
);
|
||||
|
||||
const onStateChangeRef = React.useRef(onStateChange);
|
||||
const stateRef = React.useRef(state);
|
||||
|
||||
React.useEffect(() => {
|
||||
isInitialRef.current = false;
|
||||
onStateChangeRef.current = onStateChange;
|
||||
stateRef.current = state;
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -345,9 +350,8 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
}
|
||||
}
|
||||
|
||||
const duplicateRouteNamesResult = checkDuplicateRouteNames(
|
||||
hydratedState
|
||||
);
|
||||
const duplicateRouteNamesResult =
|
||||
checkDuplicateRouteNames(hydratedState);
|
||||
|
||||
if (duplicateRouteNamesResult.length) {
|
||||
const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(
|
||||
@@ -415,17 +419,19 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
);
|
||||
|
||||
let element = (
|
||||
<ScheduleUpdateContext.Provider value={scheduleContext}>
|
||||
<NavigationBuilderContext.Provider value={builderContext}>
|
||||
<NavigationStateContext.Provider value={context}>
|
||||
<UnhandledActionContext.Provider
|
||||
value={onUnhandledAction ?? defaultOnUnhandledAction}
|
||||
>
|
||||
<EnsureSingleNavigator>{children}</EnsureSingleNavigator>
|
||||
</UnhandledActionContext.Provider>
|
||||
</NavigationStateContext.Provider>
|
||||
</NavigationBuilderContext.Provider>
|
||||
</ScheduleUpdateContext.Provider>
|
||||
<NavigationContainerRefContext.Provider value={navigation}>
|
||||
<ScheduleUpdateContext.Provider value={scheduleContext}>
|
||||
<NavigationBuilderContext.Provider value={builderContext}>
|
||||
<NavigationStateContext.Provider value={context}>
|
||||
<UnhandledActionContext.Provider
|
||||
value={onUnhandledAction ?? defaultOnUnhandledAction}
|
||||
>
|
||||
<EnsureSingleNavigator>{children}</EnsureSingleNavigator>
|
||||
</UnhandledActionContext.Provider>
|
||||
</NavigationStateContext.Provider>
|
||||
</NavigationBuilderContext.Provider>
|
||||
</ScheduleUpdateContext.Provider>
|
||||
</NavigationContainerRefContext.Provider>
|
||||
);
|
||||
|
||||
if (independent) {
|
||||
|
||||
@@ -4,8 +4,7 @@ import * as React from 'react';
|
||||
* Context which holds the values for the current navigation tree.
|
||||
* Intended for use in SSR. This is not safe to use on the client.
|
||||
*/
|
||||
const CurrentRenderContext = React.createContext<
|
||||
{ options?: object } | undefined
|
||||
>(undefined);
|
||||
const CurrentRenderContext =
|
||||
React.createContext<{ options?: object } | undefined>(undefined);
|
||||
|
||||
export default CurrentRenderContext;
|
||||
|
||||
@@ -6,13 +6,14 @@ type Props = {
|
||||
|
||||
const MULTIPLE_NAVIGATOR_ERROR = `Another navigator is already registered for this container. You likely have multiple navigators under a single "NavigationContainer" or "Screen". Make sure each navigator is under a separate "Screen" container. See https://reactnavigation.org/docs/nesting-navigators for a guide on nesting.`;
|
||||
|
||||
export const SingleNavigatorContext = React.createContext<
|
||||
| {
|
||||
register(key: string): void;
|
||||
unregister(key: string): void;
|
||||
}
|
||||
| undefined
|
||||
>(undefined);
|
||||
export const SingleNavigatorContext =
|
||||
React.createContext<
|
||||
| {
|
||||
register(key: string): void;
|
||||
unregister(key: string): void;
|
||||
}
|
||||
| undefined
|
||||
>(undefined);
|
||||
|
||||
/**
|
||||
* Component which ensures that there's only one navigator nested under it.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ParamListBase } from '@react-navigation/routers';
|
||||
|
||||
import type { RouteGroupConfig } from './types';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import type {
|
||||
NavigationAction,
|
||||
NavigationState,
|
||||
ParamListBase,
|
||||
} from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
import type { NavigationHelpers } from './types';
|
||||
|
||||
export type ListenerMap = {
|
||||
@@ -38,7 +39,10 @@ export type FocusedNavigationCallback<T> = (
|
||||
|
||||
export type FocusedNavigationListener = <T>(
|
||||
callback: FocusedNavigationCallback<T>
|
||||
) => { handled: boolean; result: T };
|
||||
) => {
|
||||
handled: boolean;
|
||||
result: T;
|
||||
};
|
||||
|
||||
export type GetStateListener = () => NavigationState;
|
||||
|
||||
@@ -57,6 +61,7 @@ const NavigationBuilderContext = React.createContext<{
|
||||
onRouteFocus?: (key: string) => void;
|
||||
onDispatchAction: (action: NavigationAction, noop: boolean) => void;
|
||||
onOptionsChange: (options: object) => void;
|
||||
stackRef?: React.MutableRefObject<string | undefined>;
|
||||
}>({
|
||||
onDispatchAction: () => undefined,
|
||||
onOptionsChange: () => undefined,
|
||||
|
||||
14
packages/core/src/NavigationContainerRefContext.tsx
Normal file
14
packages/core/src/NavigationContainerRefContext.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { ParamListBase } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
import type { NavigationContainerRef } from './types';
|
||||
|
||||
/**
|
||||
* Context which holds the route prop for a screen.
|
||||
*/
|
||||
const NavigationContainerRefContext =
|
||||
React.createContext<NavigationContainerRef<ParamListBase> | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
export default NavigationContainerRefContext;
|
||||
@@ -1,12 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import type { ParamListBase } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
import type { NavigationProp } from './types';
|
||||
|
||||
/**
|
||||
* Context which holds the navigation prop for a screen.
|
||||
*/
|
||||
const NavigationContext = React.createContext<
|
||||
NavigationProp<ParamListBase> | undefined
|
||||
>(undefined);
|
||||
const NavigationContext =
|
||||
React.createContext<NavigationProp<ParamListBase> | undefined>(undefined);
|
||||
|
||||
export default NavigationContext;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import type { ParamListBase } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
import type { NavigationHelpers } from './types';
|
||||
|
||||
/**
|
||||
* Context which holds the navigation helpers of the parent navigator.
|
||||
* Navigators should use this context in their view component.
|
||||
*/
|
||||
const NavigationHelpersContext = React.createContext<
|
||||
NavigationHelpers<ParamListBase> | undefined
|
||||
>(undefined);
|
||||
const NavigationHelpersContext =
|
||||
React.createContext<NavigationHelpers<ParamListBase> | undefined>(undefined);
|
||||
|
||||
export default NavigationHelpersContext;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import type { Route } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
/**
|
||||
* Context which holds the route prop for a screen.
|
||||
*/
|
||||
const NavigationContext = React.createContext<Route<string> | undefined>(
|
||||
undefined
|
||||
);
|
||||
const NavigationRouteContext =
|
||||
React.createContext<Route<string> | undefined>(undefined);
|
||||
|
||||
export default NavigationContext;
|
||||
export default NavigationRouteContext;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import type { NavigationState, PartialState } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
const MISSING_CONTEXT_ERROR =
|
||||
"Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.";
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import * as React from 'react';
|
||||
import type {
|
||||
Route,
|
||||
ParamListBase,
|
||||
NavigationState,
|
||||
ParamListBase,
|
||||
PartialState,
|
||||
Route,
|
||||
} from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
||||
import NavigationStateContext from './NavigationStateContext';
|
||||
import StaticContainer from './StaticContainer';
|
||||
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
||||
import useOptionsGetters from './useOptionsGetters';
|
||||
import type { NavigationProp, RouteConfigComponent } from './types';
|
||||
import useOptionsGetters from './useOptionsGetters';
|
||||
|
||||
type Props<State extends NavigationState, ScreenOptions extends {}> = {
|
||||
screen: RouteConfigComponent<ParamListBase, string> & { name: string };
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { ParamListBase, NavigationState } from '@react-navigation/routers';
|
||||
import type { RouteConfig, EventMapBase } from './types';
|
||||
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
||||
|
||||
import type { EventMapBase, RouteConfig } from './types';
|
||||
|
||||
/**
|
||||
* Empty component used for specifying route configuration.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import type { NavigationAction } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
const UnhandledActionContext = React.createContext<
|
||||
((action: NavigationAction) => void) | undefined
|
||||
>(undefined);
|
||||
const UnhandledActionContext =
|
||||
React.createContext<((action: NavigationAction) => void) | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
export default UnhandledActionContext;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import * as React from 'react';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import {
|
||||
DefaultRouterOptions,
|
||||
NavigationState,
|
||||
@@ -8,12 +6,15 @@ import {
|
||||
StackRouter,
|
||||
TabRouter,
|
||||
} from '@react-navigation/routers';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import NavigationStateContext from '../NavigationStateContext';
|
||||
import createNavigationContainerRef from '../createNavigationContainerRef';
|
||||
import MockRouter, { MockActions } from './__fixtures__/MockRouter';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import NavigationStateContext from '../NavigationStateContext';
|
||||
import Screen from '../Screen';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter, { MockActions } from './__fixtures__/MockRouter';
|
||||
|
||||
it('throws when getState is accessed without a container', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
import StaticContainer from '../StaticContainer';
|
||||
|
||||
it("doesn't update element if no props changed", () => {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
BaseRouter,
|
||||
Router,
|
||||
CommonNavigationAction,
|
||||
DefaultRouterOptions,
|
||||
NavigationState,
|
||||
Route,
|
||||
DefaultRouterOptions,
|
||||
Router,
|
||||
} from '@react-navigation/routers';
|
||||
|
||||
export type MockActions = CommonNavigationAction | { type: 'NOOP' | 'UPDATE' };
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { NavigationState, PartialState } from '@react-navigation/routers';
|
||||
|
||||
import getPathFromState from '../getPathFromState';
|
||||
import getStateFromPath from '../getStateFromPath';
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { InitialState } from '@react-navigation/routers';
|
||||
import produce from 'immer';
|
||||
import getStateFromPath from '../getStateFromPath';
|
||||
import getPathFromState from '../getPathFromState';
|
||||
|
||||
import findFocusedRoute from '../findFocusedRoute';
|
||||
import getPathFromState from '../getPathFromState';
|
||||
import getStateFromPath from '../getStateFromPath';
|
||||
|
||||
const changePath = <T extends InitialState>(state: T, path: string): T =>
|
||||
produce(state, (draftState) => {
|
||||
@@ -2419,3 +2420,57 @@ it('correctly applies initialRouteName for config with similar route names v2',
|
||||
getStateFromPath<object>(getPathFromState<object>(state, config), config)
|
||||
).toEqual(state);
|
||||
});
|
||||
|
||||
it('throws when invalid properties are specified in the config', () => {
|
||||
expect(() =>
|
||||
getStateFromPath<object>('', {
|
||||
Foo: 'foo',
|
||||
Bar: {
|
||||
path: 'bar',
|
||||
},
|
||||
} as any)
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
"Found invalid properties in the configuration:
|
||||
- Foo
|
||||
- Bar
|
||||
|
||||
Did you forget to specify them under a 'screens' property?
|
||||
|
||||
You can only specify the following properties:
|
||||
- initialRouteName
|
||||
- screens
|
||||
|
||||
See https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration."
|
||||
`);
|
||||
|
||||
expect(() =>
|
||||
getStateFromPath<object>('', {
|
||||
screens: {
|
||||
Foo: 'foo',
|
||||
Bar: {
|
||||
path: 'bar',
|
||||
},
|
||||
Baz: {
|
||||
Qux: {
|
||||
path: 'qux',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any)
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
"Found invalid properties in the configuration:
|
||||
- Qux
|
||||
|
||||
Did you forget to specify them under a 'screens' property?
|
||||
|
||||
You can only specify the following properties:
|
||||
- initialRouteName
|
||||
- screens
|
||||
- path
|
||||
- exact
|
||||
- stringify
|
||||
- parse
|
||||
|
||||
See https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration."
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import createNavigationContainerRef from '../createNavigationContainerRef';
|
||||
import Group from '../Group';
|
||||
import Screen from '../Screen';
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import createNavigationContainerRef from '../createNavigationContainerRef';
|
||||
import useNavigation from '../useNavigation';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter, { MockRouterKey } from './__fixtures__/MockRouter';
|
||||
|
||||
beforeEach(() => (MockRouterKey.current = 0));
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import type {
|
||||
DefaultRouterOptions,
|
||||
NavigationState,
|
||||
Router,
|
||||
} from '@react-navigation/routers';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter, {
|
||||
MockActions,
|
||||
MockRouterKey,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { NavigationState, Router } from '@react-navigation/routers';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import type { Router, NavigationState } from '@react-navigation/routers';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
|
||||
it('fires focus and blur events in root navigator', () => {
|
||||
@@ -30,19 +31,21 @@ it('fires focus and blur events in root navigator', () => {
|
||||
const fourthFocusCallback = jest.fn();
|
||||
const fourthBlurCallback = jest.fn();
|
||||
|
||||
const createComponent = (focusCallback: any, blurCallback: any) => ({
|
||||
navigation,
|
||||
}: any) => {
|
||||
React.useEffect(() => navigation.addListener('focus', focusCallback), [
|
||||
navigation,
|
||||
]);
|
||||
const createComponent =
|
||||
(focusCallback: any, blurCallback: any) =>
|
||||
({ navigation }: any) => {
|
||||
React.useEffect(
|
||||
() => navigation.addListener('focus', focusCallback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
React.useEffect(() => navigation.addListener('blur', blurCallback), [
|
||||
navigation,
|
||||
]);
|
||||
React.useEffect(
|
||||
() => navigation.addListener('blur', blurCallback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
const navigation = React.createRef<any>();
|
||||
|
||||
@@ -184,19 +187,21 @@ it('fires focus and blur events in nested navigator', () => {
|
||||
const fourthFocusCallback = jest.fn();
|
||||
const fourthBlurCallback = jest.fn();
|
||||
|
||||
const createComponent = (focusCallback: any, blurCallback: any) => ({
|
||||
navigation,
|
||||
}: any) => {
|
||||
React.useEffect(() => navigation.addListener('focus', focusCallback), [
|
||||
navigation,
|
||||
]);
|
||||
const createComponent =
|
||||
(focusCallback: any, blurCallback: any) =>
|
||||
({ navigation }: any) => {
|
||||
React.useEffect(
|
||||
() => navigation.addListener('focus', focusCallback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
React.useEffect(() => navigation.addListener('blur', blurCallback), [
|
||||
navigation,
|
||||
]);
|
||||
React.useEffect(
|
||||
() => navigation.addListener('blur', blurCallback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
const parent = React.createRef<any>();
|
||||
const child = React.createRef<any>();
|
||||
@@ -391,9 +396,10 @@ it('fires blur event when a route is removed with a delay', async () => {
|
||||
const First = () => null;
|
||||
|
||||
const Second = ({ navigation }: any) => {
|
||||
React.useEffect(() => navigation.addListener('blur', blurCallback), [
|
||||
navigation,
|
||||
]);
|
||||
React.useEffect(
|
||||
() => navigation.addListener('blur', blurCallback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -446,13 +452,16 @@ it('fires custom events added with addListener', () => {
|
||||
const secondCallback = jest.fn();
|
||||
const thirdCallback = jest.fn();
|
||||
|
||||
const createComponent = (callback: any) => ({ navigation }: any) => {
|
||||
React.useEffect(() => navigation.addListener(eventName, callback), [
|
||||
navigation,
|
||||
]);
|
||||
const createComponent =
|
||||
(callback: any) =>
|
||||
({ navigation }: any) => {
|
||||
React.useEffect(
|
||||
() => navigation.addListener(eventName, callback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
const ref = React.createRef<any>();
|
||||
|
||||
@@ -525,9 +534,10 @@ it("doesn't call same listener multiple times with addListener", () => {
|
||||
const callback = jest.fn();
|
||||
|
||||
const Test = ({ navigation }: any) => {
|
||||
React.useEffect(() => navigation.addListener(eventName, callback), [
|
||||
navigation,
|
||||
]);
|
||||
React.useEffect(
|
||||
() => navigation.addListener(eventName, callback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -801,9 +811,10 @@ it('has option to prevent default', () => {
|
||||
};
|
||||
|
||||
const Test = ({ navigation }: any) => {
|
||||
React.useEffect(() => navigation.addListener(eventName, callback), [
|
||||
navigation,
|
||||
]);
|
||||
React.useEffect(
|
||||
() => navigation.addListener(eventName, callback),
|
||||
[navigation]
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useFocusEffect from '../useFocusEffect';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useFocusEffect from '../useFocusEffect';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
|
||||
it('runs focus effect on focus change', () => {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useIsFocused from '../useIsFocused';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useIsFocused from '../useIsFocused';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
|
||||
it('renders correct focus state', () => {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useNavigation from '../useNavigation';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useNavigation from '../useNavigation';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
|
||||
it('gets navigation prop from context', () => {
|
||||
@@ -106,13 +107,40 @@ it("gets navigation's parent's parent from context", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('gets navigation from container from context', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const TestNavigator = (props: any): any => {
|
||||
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
|
||||
|
||||
return state.routes.map((route) => descriptors[route.key].render());
|
||||
};
|
||||
|
||||
const Test = () => {
|
||||
const navigation = useNavigation();
|
||||
|
||||
expect(navigation.navigate).toBeDefined();
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
render(
|
||||
<BaseNavigationContainer>
|
||||
<Test />
|
||||
<TestNavigator>
|
||||
<Screen name="foo">{() => null}</Screen>
|
||||
</TestNavigator>
|
||||
</BaseNavigationContainer>
|
||||
);
|
||||
});
|
||||
|
||||
it('throws if called outside a navigation context', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const Test = () => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
expect(() => useNavigation()).toThrow(
|
||||
"Couldn't find a navigation object. Is your component inside a screen in a navigator?"
|
||||
"Couldn't find a navigation object. Is your component inside NavigationContainer?"
|
||||
);
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import useEventEmitter from '../useEventEmitter';
|
||||
import useNavigationCache from '../useNavigationCache';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useEventEmitter from '../useEventEmitter';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useNavigationCache from '../useNavigationCache';
|
||||
import MockRouter, { MockRouterKey } from './__fixtures__/MockRouter';
|
||||
|
||||
beforeEach(() => (MockRouterKey.current = 0));
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as React from 'react';
|
||||
import { render, act } from '@testing-library/react-native';
|
||||
import type { NavigationState } from '@react-navigation/routers';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useNavigationState from '../useNavigationState';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useNavigationState from '../useNavigationState';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
|
||||
it('gets the current navigation state', () => {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import {
|
||||
Router,
|
||||
DefaultRouterOptions,
|
||||
NavigationState,
|
||||
StackRouter,
|
||||
ParamListBase,
|
||||
Router,
|
||||
StackRouter,
|
||||
} from '@react-navigation/routers';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import createNavigationContainerRef from '../createNavigationContainerRef';
|
||||
import Screen from '../Screen';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import MockRouter, {
|
||||
MockActions,
|
||||
MockRouterKey,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useRoute from '../useRoute';
|
||||
import * as React from 'react';
|
||||
|
||||
import BaseNavigationContainer from '../BaseNavigationContainer';
|
||||
import Screen from '../Screen';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
import type { RouteProp } from '../types';
|
||||
import useNavigationBuilder from '../useNavigationBuilder';
|
||||
import useRoute from '../useRoute';
|
||||
import MockRouter from './__fixtures__/MockRouter';
|
||||
|
||||
it('gets route prop from context', () => {
|
||||
expect.assertions(1);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { CommonActions } from '@react-navigation/routers';
|
||||
|
||||
import type { NavigationContainerRefWithCurrent } from './types';
|
||||
|
||||
export const NOT_INITIALIZED_ERROR =
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
||||
import type * as React from 'react';
|
||||
import type { ParamListBase, NavigationState } from '@react-navigation/routers';
|
||||
|
||||
import Group from './Group';
|
||||
import Screen from './Screen';
|
||||
import type { TypedNavigator, EventMapBase } from './types';
|
||||
import type { EventMapBase, TypedNavigator } from './types';
|
||||
|
||||
/**
|
||||
* Higher order component to create a `Navigator` and `Screen` pair.
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type {
|
||||
Route,
|
||||
PartialRoute,
|
||||
ParamListBase,
|
||||
NavigationState,
|
||||
PartialState,
|
||||
CommonActions,
|
||||
NavigationState,
|
||||
ParamListBase,
|
||||
PartialRoute,
|
||||
PartialState,
|
||||
Route,
|
||||
} from '@react-navigation/routers';
|
||||
import type { PathConfig, PathConfigMap, NavigatorScreenParams } from './types';
|
||||
|
||||
import type { NavigatorScreenParams, PathConfig, PathConfigMap } from './types';
|
||||
|
||||
type ConfigItem = {
|
||||
initialRouteName?: string;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Route } from '@react-navigation/routers';
|
||||
|
||||
import { CHILD_STATE } from './useRouteCache';
|
||||
|
||||
export default function getFocusedRouteNameFromRoute(
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import * as queryString from 'query-string';
|
||||
import type {
|
||||
NavigationState,
|
||||
PartialState,
|
||||
Route,
|
||||
} from '@react-navigation/routers';
|
||||
import * as queryString from 'query-string';
|
||||
|
||||
import fromEntries from './fromEntries';
|
||||
import type { PathConfig, PathConfigMap } from './types';
|
||||
import validatePathConfig from './validatePathConfig';
|
||||
|
||||
type Options<ParamList> = {
|
||||
initialRouteName?: string;
|
||||
@@ -74,6 +76,10 @@ export default function getPathFromState<ParamList extends {}>(
|
||||
);
|
||||
}
|
||||
|
||||
if (options) {
|
||||
validatePathConfig(options);
|
||||
}
|
||||
|
||||
// Create a normalized configs object which will be easier to use
|
||||
const configs: Record<string, ConfigItem> = options?.screens
|
||||
? createNormalizedConfigs(options?.screens)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import escape from 'escape-string-regexp';
|
||||
import * as queryString from 'query-string';
|
||||
import type {
|
||||
InitialState,
|
||||
NavigationState,
|
||||
PartialState,
|
||||
InitialState,
|
||||
} from '@react-navigation/routers';
|
||||
import escape from 'escape-string-regexp';
|
||||
import * as queryString from 'query-string';
|
||||
|
||||
import findFocusedRoute from './findFocusedRoute';
|
||||
import type { PathConfigMap } from './types';
|
||||
import validatePathConfig from './validatePathConfig';
|
||||
|
||||
type Options<ParamList extends {}> = {
|
||||
initialRouteName?: string;
|
||||
@@ -64,6 +66,10 @@ export default function getStateFromPath<ParamList extends {}>(
|
||||
path: string,
|
||||
options?: Options<ParamList>
|
||||
): ResultState | undefined {
|
||||
if (options) {
|
||||
validatePathConfig(options);
|
||||
}
|
||||
|
||||
let initialRoutes: InitialRouteConfig[] = [];
|
||||
|
||||
if (options?.initialRouteName) {
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
export * from '@react-navigation/routers';
|
||||
|
||||
export { default as BaseNavigationContainer } from './BaseNavigationContainer';
|
||||
export { default as createNavigatorFactory } from './createNavigatorFactory';
|
||||
|
||||
export { default as createNavigationContainerRef } from './createNavigationContainerRef';
|
||||
export { default as useNavigationContainerRef } from './useNavigationContainerRef';
|
||||
|
||||
export { default as NavigationHelpersContext } from './NavigationHelpersContext';
|
||||
export { default as NavigationContext } from './NavigationContext';
|
||||
export { default as NavigationRouteContext } from './NavigationRouteContext';
|
||||
|
||||
export { default as createNavigatorFactory } from './createNavigatorFactory';
|
||||
export { default as CurrentRenderContext } from './CurrentRenderContext';
|
||||
|
||||
export { default as useNavigationBuilder } from './useNavigationBuilder';
|
||||
export { default as useNavigation } from './useNavigation';
|
||||
export { default as useRoute } from './useRoute';
|
||||
export { default as findFocusedRoute } from './findFocusedRoute';
|
||||
export { default as getActionFromState } from './getActionFromState';
|
||||
export { default as getFocusedRouteNameFromRoute } from './getFocusedRouteNameFromRoute';
|
||||
export { default as getPathFromState } from './getPathFromState';
|
||||
export { default as getStateFromPath } from './getStateFromPath';
|
||||
export { default as NavigationContainerRefContext } from './NavigationContainerRefContext';
|
||||
export { default as NavigationContext } from './NavigationContext';
|
||||
export { default as NavigationHelpersContext } from './NavigationHelpersContext';
|
||||
export { default as NavigationRouteContext } from './NavigationRouteContext';
|
||||
export * from './types';
|
||||
export { default as useFocusEffect } from './useFocusEffect';
|
||||
export { default as useIsFocused } from './useIsFocused';
|
||||
export { default as useNavigation } from './useNavigation';
|
||||
export { default as useNavigationBuilder } from './useNavigationBuilder';
|
||||
export { default as useNavigationContainerRef } from './useNavigationContainerRef';
|
||||
export { default as useNavigationState } from './useNavigationState';
|
||||
|
||||
export { default as getStateFromPath } from './getStateFromPath';
|
||||
export { default as getPathFromState } from './getPathFromState';
|
||||
export { default as getActionFromState } from './getActionFromState';
|
||||
|
||||
export { default as findFocusedRoute } from './findFocusedRoute';
|
||||
|
||||
export { default as getFocusedRouteNameFromRoute } from './getFocusedRouteNameFromRoute';
|
||||
|
||||
export * from './types';
|
||||
export { default as useRoute } from './useRoute';
|
||||
export { default as validatePathConfig } from './validatePathConfig';
|
||||
export * from '@react-navigation/routers';
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type * as React from 'react';
|
||||
import type {
|
||||
DefaultRouterOptions,
|
||||
NavigationState,
|
||||
NavigationAction,
|
||||
InitialState,
|
||||
NavigationAction,
|
||||
NavigationState,
|
||||
ParamListBase,
|
||||
PartialState,
|
||||
Route,
|
||||
ParamListBase,
|
||||
} from '@react-navigation/routers';
|
||||
import type * as React from 'react';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
@@ -20,14 +20,25 @@ declare global {
|
||||
type Keyof<T extends {}> = Extract<keyof T, string>;
|
||||
|
||||
export type DefaultNavigatorOptions<
|
||||
ParamList extends ParamListBase,
|
||||
State extends NavigationState,
|
||||
ScreenOptions extends {},
|
||||
ParamList extends ParamListBase = ParamListBase
|
||||
EventMap extends EventMapBase
|
||||
> = DefaultRouterOptions<Keyof<ParamList>> & {
|
||||
/**
|
||||
* Children React Elements to extract the route configuration from.
|
||||
* Only `Screen`, `Group` and `React.Fragment` are supported as children.
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* Event listeners for all the screens in the navigator.
|
||||
*/
|
||||
screenListeners?:
|
||||
| ScreenListeners<State, EventMap>
|
||||
| ((props: {
|
||||
route: RouteProp<ParamList>;
|
||||
navigation: any;
|
||||
}) => ScreenListeners<State, EventMap>);
|
||||
/**
|
||||
* Default options for all screens under this navigator.
|
||||
*/
|
||||
@@ -513,43 +524,45 @@ export type NavigationContainerEventMap = {
|
||||
* Whether the action was a no-op, i.e. resulted any state changes.
|
||||
*/
|
||||
noop: boolean;
|
||||
/**
|
||||
* Stack trace of the action, this will only be available during development.
|
||||
*/
|
||||
stack: string | undefined;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type NavigationContainerRef<
|
||||
ParamList extends {}
|
||||
> = NavigationHelpers<ParamList> &
|
||||
EventConsumer<NavigationContainerEventMap> & {
|
||||
/**
|
||||
* Reset the navigation state of the root navigator to the provided state.
|
||||
*
|
||||
* @param state Navigation state object.
|
||||
*/
|
||||
resetRoot(state?: PartialState<NavigationState> | NavigationState): void;
|
||||
/**
|
||||
* Get the rehydrated navigation state of the navigation tree.
|
||||
*/
|
||||
getRootState(): NavigationState;
|
||||
/**
|
||||
* Get the currently focused navigation route.
|
||||
*/
|
||||
getCurrentRoute(): Route<string> | undefined;
|
||||
/**
|
||||
* Get the currently focused route's options.
|
||||
*/
|
||||
getCurrentOptions(): object | undefined;
|
||||
/**
|
||||
* Whether the navigation container is ready to handle actions.
|
||||
*/
|
||||
isReady(): boolean;
|
||||
};
|
||||
export type NavigationContainerRef<ParamList extends {}> =
|
||||
NavigationHelpers<ParamList> &
|
||||
EventConsumer<NavigationContainerEventMap> & {
|
||||
/**
|
||||
* Reset the navigation state of the root navigator to the provided state.
|
||||
*
|
||||
* @param state Navigation state object.
|
||||
*/
|
||||
resetRoot(state?: PartialState<NavigationState> | NavigationState): void;
|
||||
/**
|
||||
* Get the rehydrated navigation state of the navigation tree.
|
||||
*/
|
||||
getRootState(): NavigationState;
|
||||
/**
|
||||
* Get the currently focused navigation route.
|
||||
*/
|
||||
getCurrentRoute(): Route<string> | undefined;
|
||||
/**
|
||||
* Get the currently focused route's options.
|
||||
*/
|
||||
getCurrentOptions(): object | undefined;
|
||||
/**
|
||||
* Whether the navigation container is ready to handle actions.
|
||||
*/
|
||||
isReady(): boolean;
|
||||
};
|
||||
|
||||
export type NavigationContainerRefWithCurrent<
|
||||
ParamList extends {}
|
||||
> = NavigationContainerRef<ParamList> & {
|
||||
current: NavigationContainerRef<ParamList> | null;
|
||||
};
|
||||
export type NavigationContainerRefWithCurrent<ParamList extends {}> =
|
||||
NavigationContainerRef<ParamList> & {
|
||||
current: NavigationContainerRef<ParamList> | null;
|
||||
};
|
||||
|
||||
export type TypedNavigator<
|
||||
ParamList extends ParamListBase,
|
||||
@@ -564,9 +577,9 @@ export type TypedNavigator<
|
||||
Navigator: React.ComponentType<
|
||||
Omit<
|
||||
React.ComponentProps<Navigator>,
|
||||
keyof DefaultNavigatorOptions<any, any>
|
||||
keyof DefaultNavigatorOptions<any, any, any, any>
|
||||
> &
|
||||
DefaultNavigatorOptions<ScreenOptions, ParamList>
|
||||
DefaultNavigatorOptions<ParamList, State, ScreenOptions, EventMap>
|
||||
>;
|
||||
/**
|
||||
* Component used for grouping multiple route configuration.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import type { ListenerMap } from './NavigationBuilderContext';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
||||
import * as React from 'react';
|
||||
|
||||
import CurrentRenderContext from './CurrentRenderContext';
|
||||
import type {
|
||||
Descriptor,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user