mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-22 03:48:18 +08:00
Compare commits
35 Commits
@react-nav
...
fix/sortOn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
073f04b6eb | ||
|
|
ed37e6aec0 | ||
|
|
f80ed7790e | ||
|
|
4c16083d51 | ||
|
|
e7631ea239 | ||
|
|
32fe3f17d0 | ||
|
|
b7c5305453 | ||
|
|
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 |
@@ -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
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
31
.github/workflows/closed-issue.yml
vendored
Normal file
31
.github/workflows/closed-issue.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Comment on closed issue
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
closed-issue:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.issue.state == 'closed' }}
|
||||
steps:
|
||||
- uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const body = "Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.";
|
||||
const comments = await github.issues.listComments({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
});
|
||||
|
||||
if (comments.data.some(comment => comment.body === body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await github.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body,
|
||||
});
|
||||
5
.github/workflows/expo-preview.yml
vendored
5
.github/workflows/expo-preview.yml
vendored
@@ -16,10 +16,9 @@ jobs:
|
||||
node-version: 14.x
|
||||
|
||||
- name: Setup Expo
|
||||
uses: expo/expo-github-action@v5
|
||||
uses: expo/expo-github-action@v6
|
||||
with:
|
||||
expo-token: ${{ secrets.EXPO_TOKEN }}
|
||||
expo-cache: true
|
||||
token: ${{ secrets.EXPO_TOKEN }}
|
||||
|
||||
- name: Restore yarn cache
|
||||
id: yarn-cache
|
||||
|
||||
5
.github/workflows/expo.yml
vendored
5
.github/workflows/expo.yml
vendored
@@ -19,10 +19,9 @@ jobs:
|
||||
node-version: 14.x
|
||||
|
||||
- name: Setup Expo
|
||||
uses: expo/expo-github-action@v5
|
||||
uses: expo/expo-github-action@v6
|
||||
with:
|
||||
expo-token: ${{ secrets.EXPO_TOKEN }}
|
||||
expo-cache: true
|
||||
token: ${{ secrets.EXPO_TOKEN }}
|
||||
|
||||
- name: Restore yarn cache
|
||||
id: yarn-cache
|
||||
|
||||
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,19 +1,20 @@
|
||||
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';
|
||||
|
||||
|
||||
@@ -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,57 @@
|
||||
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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-navigation/bottom-tabs",
|
||||
"description": "Bottom tab navigator following iOS design guidelines",
|
||||
"version": "6.0.0-next.13",
|
||||
"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.12",
|
||||
"@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) => {
|
||||
@@ -2195,6 +2196,7 @@ it('tries to match wildcard patterns at the end', () => {
|
||||
path: '/bar/:id/',
|
||||
screens: {
|
||||
404: '*',
|
||||
UserProfile: ':userSlug',
|
||||
Test: 'test',
|
||||
},
|
||||
},
|
||||
@@ -2419,3 +2421,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) {
|
||||
@@ -137,27 +143,31 @@ export default function getStateFromPath<ParamList extends {}>(
|
||||
const aParts = a.pattern.split('/');
|
||||
const bParts = b.pattern.split('/');
|
||||
|
||||
const aWildcardIndex = aParts.indexOf('*');
|
||||
const bWildcardIndex = bParts.indexOf('*');
|
||||
|
||||
// If only one of the patterns has a wildcard, move it down in the list
|
||||
if (aWildcardIndex === -1 && bWildcardIndex !== -1) {
|
||||
return -1;
|
||||
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
|
||||
// if b is longer, b get higher priority
|
||||
if (aParts[i] == null) {
|
||||
return 1;
|
||||
}
|
||||
// if a is longer, a get higher priority
|
||||
if (bParts[i] == null) {
|
||||
return -1;
|
||||
}
|
||||
const aWildCard = aParts[i] === '*' || aParts[i].startsWith(':');
|
||||
const bWildCard = bParts[i] === '*' || bParts[i].startsWith(':');
|
||||
// if both are wildcard we compare next component
|
||||
if (aWildCard && bWildCard) {
|
||||
continue;
|
||||
}
|
||||
// if only a is wild card, b get higher priority
|
||||
if (aWildCard) {
|
||||
return 1;
|
||||
}
|
||||
// if only b is wild card, a get higher priority
|
||||
if (bWildCard) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (aWildcardIndex !== -1 && bWildcardIndex === -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (aWildcardIndex === bWildcardIndex) {
|
||||
// If `b` has more `/`, it's more exhaustive
|
||||
// So we move it up in the list
|
||||
return bParts.length - aParts.length;
|
||||
}
|
||||
|
||||
// If the wildcard appears later in the pattern (has higher index), it's more specific
|
||||
// So we move it up in the list
|
||||
return bWildcardIndex - aWildcardIndex;
|
||||
return bParts.length - aParts.length;
|
||||
});
|
||||
|
||||
// Check for duplicate patterns in the config
|
||||
|
||||
@@ -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';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user