Compare commits

..

21 Commits

Author SHA1 Message Date
Satyajit Sahoo
6dce0780ed chore: publish
- @react-navigation/stack@5.3.3
2020-05-11 17:31:35 +02:00
Hein Rutjes
dd7cff2016 fix: fix ios transitionspec settle time (#8028)
# Why

When using the stack navigator on iOS, it takes a (too) long time before the  `didFocus` and stack `onTransitionEnd` lifecycle events are triggered. The visual animation is typically completed well within 500 msec, but it takes around 1000 msec before the previously mentioned events are emitted. This causes problems with for instance `react-navigation-shared-element`, which relies on these events to fire in a timely manner(https://github.com/IjzerenHein/react-navigation-shared-element/issues/24)

# How

This PR updates the resting threshold so that the underlying spring settles faster. No visual differences or differences in smoothness were witnessed during testing.

## Before

Time to settle `didFocus`: **941**
Time to settle `stack.onTransitionEnd`: **924**

```
15:59:55.743 [ListViewStack]startTransition, closing: false, nestingDepth: 1
15:59:55.744 [ListViewStack]willFocus, scene: "DetailScreen", depth: 1, closing: false
15:59:55.745 Transition start: "ListScreen" -> "DetailScreen"
15:59:56.667 [ListViewStack]endTransition, closing: false, nestingDepth: 1
15:59:56.668 Transition end: "DetailScreen"
15:59:56.685 [ListViewStack]didFocus, scene: "DetailScreen", depth: 1
```

## After

Time to settle `didFocus`: **529**
Time to settle `stack.onTransitionEnd`: **512**

```
15:55:00.686 [ListViewStack]startTransition, closing: false, nestingDepth: 1
15:55:00.687 [ListViewStack]willFocus, scene: "DetailScreen", depth: 1, closing: false
15:55:00.687 Transition start: "ListScreen" -> "DetailScreen"
15:55:01.198 [ListViewStack]endTransition, closing: false, nestingDepth: 1
15:55:01.199 Transition end: "DetailScreen"
15:55:01.216 [ListViewStack]didFocus, scene: "DetailScreen", depth: 1
2020-05-11 17:03:12 +02:00
Satyajit Sahoo
740c6b6706 chore: publish
- @react-navigation/bottom-tabs@5.4.2
 - @react-navigation/compat@5.1.18
 - @react-navigation/drawer@5.7.2
 - @react-navigation/material-bottom-tabs@5.2.2
 - @react-navigation/material-top-tabs@5.2.2
 - @react-navigation/native@5.3.0
 - @react-navigation/stack@5.3.2
2020-05-10 08:34:40 +02:00
Satyajit Sahoo
039017bc2a feat: initialState should take priority over deep link 2020-05-10 08:28:48 +02:00
Satyajit Sahoo
b85a1c3055 chore: publish
- @react-navigation/bottom-tabs@5.4.1
 - @react-navigation/compat@5.1.17
 - @react-navigation/core@5.5.2
 - @react-navigation/drawer@5.7.1
 - @react-navigation/material-bottom-tabs@5.2.1
 - @react-navigation/material-top-tabs@5.2.1
 - @react-navigation/native@5.2.6
 - @react-navigation/routers@5.4.4
 - @react-navigation/stack@5.3.1
2020-05-08 19:16:47 +02:00
Satyajit Sahoo
18f8188dc8 chore: add source key to package.json 2020-05-08 19:14:29 +02:00
Satyajit Sahoo
47a1229837 fix: fix building typescript definitions. closes #8216 2020-05-08 19:09:13 +02:00
Satyajit Sahoo
00b11e303e chore: publish
- @react-navigation/bottom-tabs@5.4.0
 - @react-navigation/compat@5.1.16
 - @react-navigation/core@5.5.1
 - @react-navigation/drawer@5.7.0
 - @react-navigation/material-bottom-tabs@5.2.0
 - @react-navigation/material-top-tabs@5.2.0
 - @react-navigation/native@5.2.5
 - @react-navigation/routers@5.4.3
 - @react-navigation/stack@5.3.0
2020-05-08 16:34:03 +02:00
Satyajit Sahoo
f384706741 feat: use links in bottom navigation tabs 2020-05-08 16:11:24 +02:00
Satyajit Sahoo
d1a6f3e30e chore: upgrade depenendecies 2020-05-08 16:06:28 +02:00
Satyajit Sahoo
fd6636a8cd chore: update circleci config 2020-05-08 03:19:47 +02:00
Satyajit Sahoo
eb24fea8b9 chore: upgrade depenendecies 2020-05-07 21:08:55 +02:00
Linus Unnebäck
85ae378d8c fix: return a promise-like from getInitialState (#8210) 2020-05-07 20:56:55 +02:00
Satyajit Sahoo
bea14aa26f feat: add generic type aliases for screen props
closes #7971
2020-05-06 19:00:04 +02:00
Satyajit Sahoo
4d1e102f8c fix: include safe are insets in title's margins 2020-05-06 16:49:02 +02:00
Satyajit Sahoo
f07cd13561 fix: add proper margins to the header title 2020-05-06 16:14:40 +02:00
Satyajit Sahoo
f6d06768d3 fix: avoid cleaning up state when a new navigator is mounted. fixes #8195 2020-05-06 15:49:59 +02:00
Satyajit Sahoo
3381d680d7 chore: publish
- @react-navigation/bottom-tabs@5.3.4
 - @react-navigation/compat@5.1.15
 - @react-navigation/core@5.5.0
 - @react-navigation/drawer@5.6.4
 - @react-navigation/material-bottom-tabs@5.1.15
 - @react-navigation/material-top-tabs@5.1.15
 - @react-navigation/native@5.2.4
 - @react-navigation/stack@5.2.19
2020-05-05 20:07:13 +02:00
Wojciech Lewicki
fcd1cc64c1 feat: add support for optional params to linking (#8196) 2020-05-05 17:18:34 +02:00
Wojciech Lewicki
3999fc2836 feat: support params anywhere in path segement (#8184) 2020-05-04 15:07:27 +02:00
Satyajit Sahoo
9fd2635756 fix: return undefined for buildLink if linking is not enabled 2020-05-04 06:35:22 +02:00
51 changed files with 3152 additions and 1139 deletions

View File

@@ -1,46 +1,54 @@
version: 2 version: 2.1
defaults: &defaults executors:
default:
docker: docker:
- image: circleci/node:10 - image: circleci/node:10
working_directory: ~/project working_directory: ~/project
environment:
YARN_CACHE_FOLDER: "~/.cache/yarn"
commands:
attach_project:
steps:
- attach_workspace:
at: ~/project
jobs: jobs:
install-dependencies: install-dependencies:
<<: *defaults executor: default
steps: steps:
- checkout - checkout
- attach_workspace: - attach_project
at: ~/project
- restore_cache: - restore_cache:
keys: keys:
- v1-dependencies-{{ checksum "yarn.lock" }} - v2-dependencies-{{ checksum "yarn.lock" }}
- v1-dependencies- - v2-dependencies-
- run: - run:
name: Install project dependencies name: Install project dependencies
command: yarn install --frozen-lockfile command: yarn install --frozen-lockfile
- save_cache: - save_cache:
key: v1-dependencies-{{ checksum "yarn.lock" }} key: v2-dependencies-{{ checksum "yarn.lock" }}
paths: node_modules paths: ~/.cache/yarn
- persist_to_workspace: - persist_to_workspace:
root: . root: .
paths: . paths: .
lint-and-typecheck: lint-and-typecheck:
<<: *defaults executor: default
steps: steps:
- attach_workspace: - attach_project
at: ~/project
- run: - run:
name: Lint files name: Lint files
command: yarn lint command: yarn lint
- run: - run:
name: Typecheck files name: Typecheck files
command: yarn typescript command: yarn typescript
unit-tests: unit-tests:
<<: *defaults executor: default
steps: steps:
- attach_workspace: - attach_project
at: ~/project
- run: - run:
name: Run unit tests name: Run unit tests
command: yarn test --coverage command: yarn test --coverage
@@ -50,11 +58,11 @@ jobs:
- store_artifacts: - store_artifacts:
path: coverage path: coverage
destination: coverage destination: coverage
integration-tests: integration-tests:
<<: *defaults executor: default
steps: steps:
- attach_workspace: - attach_project
at: ~/project
- run: - run:
name: Install Headless Chrome dependencies name: Install Headless Chrome dependencies
command: | command: |
@@ -70,11 +78,11 @@ jobs:
- run: - run:
name: Run integration tests name: Run integration tests
command: yarn example test --maxWorkers=2 command: yarn example test --maxWorkers=2
build-packages: build-packages:
<<: *defaults executor: default
steps: steps:
- attach_workspace: - attach_project
at: ~/project
- run: - run:
name: Build packages in the monorepo name: Build packages in the monorepo
command: yarn lerna run prepare command: yarn lerna run prepare
@@ -83,7 +91,6 @@ jobs:
command: node scripts/check-types-path.js command: node scripts/check-types-path.js
workflows: workflows:
version: 2
build-and-test: build-and-test:
jobs: jobs:
- install-dependencies - install-dependencies

View File

@@ -12,33 +12,33 @@
"test": "jest" "test": "jest"
}, },
"dependencies": { "dependencies": {
"@expo/vector-icons": "^10.0.0", "@expo/vector-icons": "^10.2.0",
"@react-native-community/masked-view": "^0.1.7", "@react-native-community/masked-view": "^0.1.10",
"color": "^3.1.2", "color": "^3.1.2",
"expo": "^37.0.0", "expo": "^37.0.8",
"expo-asset": "~8.1.3", "expo-asset": "~8.1.3",
"expo-blur": "~8.1.0", "expo-blur": "~8.1.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-dom": "~16.9.0", "react-dom": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0", "react-native-gesture-handler": "^1.6.0",
"react-native-paper": "^3.7.0", "react-native-paper": "^3.10.1",
"react-native-reanimated": "^1.7.0", "react-native-reanimated": "^1.8.0",
"react-native-restart": "^0.0.14", "react-native-restart": "^0.0.15",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0", "react-native-screens": "^2.7.0",
"react-native-tab-view": "2.14.0", "react-native-tab-view": "2.14.0",
"react-native-unimodules": "~0.8.1", "react-native-unimodules": "~0.9.1",
"react-native-web": "^0.11.7" "react-native-web": "^0.11.7"
}, },
"devDependencies": { "devDependencies": {
"@expo/webpack-config": "^0.11.19", "@expo/webpack-config": "^0.11.19",
"@types/jest-dev-server": "^4.2.0", "@types/jest-dev-server": "^4.2.0",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.60.22", "@types/react-native": "^0.62.7",
"babel-preset-expo": "^8.1.0", "babel-preset-expo": "^8.1.0",
"expo-cli": "^3.17.18", "expo-cli": "^3.20.1",
"jest": "^25.2.7", "jest": "^26.0.1",
"jest-dev-server": "^4.4.0", "jest-dev-server": "^4.4.0",
"playwright": "^0.14.0", "playwright": "^0.14.0",
"serve": "^11.3.0", "serve": "^11.3.0",

View File

@@ -7,6 +7,7 @@ import {
I18nManager, I18nManager,
Dimensions, Dimensions,
ScaledSize, ScaledSize,
Linking,
} from 'react-native'; } from 'react-native';
// eslint-disable-next-line import/no-unresolved // eslint-disable-next-line import/no-unresolved
import { enableScreens } from 'react-native-screens'; import { enableScreens } from 'react-native-screens';
@@ -138,19 +139,19 @@ export default function App() {
React.useEffect(() => { React.useEffect(() => {
const restoreState = async () => { const restoreState = async () => {
try { try {
let state; const initialUrl = await Linking.getInitialURL();
if (Platform.OS !== 'web' && state === undefined) { if (Platform.OS !== 'web' || initialUrl === null) {
const savedState = await AsyncStorage.getItem( const savedState = await AsyncStorage.getItem(
NAVIGATION_PERSISTENCE_KEY NAVIGATION_PERSISTENCE_KEY
); );
state = savedState ? JSON.parse(savedState) : undefined; const state = savedState ? JSON.parse(savedState) : undefined;
}
if (state !== undefined) { if (state !== undefined) {
setInitialState(state); setInitialState(state);
} }
}
} finally { } finally {
try { try {
const themeName = await AsyncStorage.getItem(THEME_PERSISTENCE_KEY); const themeName = await AsyncStorage.getItem(THEME_PERSISTENCE_KEY);

View File

@@ -24,17 +24,19 @@ module.exports = async function (env, argv) {
); );
Object.assign(config.resolve.alias, { Object.assign(config.resolve.alias, {
react: path.resolve(node_modules, 'react'), 'react': path.resolve(node_modules, 'react'),
'react-native': path.resolve(node_modules, 'react-native-web'), 'react-native': path.resolve(node_modules, 'react-native-web'),
'react-native-web': path.resolve(node_modules, 'react-native-web'), 'react-native-web': path.resolve(node_modules, 'react-native-web'),
'@expo/vector-icons': path.resolve(node_modules, '@expo/vector-icons'), '@expo/vector-icons': path.resolve(node_modules, '@expo/vector-icons'),
}); });
fs.readdirSync(packages).forEach((name) => { fs.readdirSync(packages)
.filter((name) => !name.startsWith('.'))
.forEach((name) => {
config.resolve.alias[`@react-navigation/${name}`] = path.resolve( config.resolve.alias[`@react-navigation/${name}`] = path.resolve(
packages, packages,
name, name,
'src' require(`../packages/${name}/package.json`).source
); );
}); });

View File

@@ -27,23 +27,23 @@
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.9.0", "@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/preset-env": "^7.9.0", "@babel/preset-env": "^7.9.6",
"@babel/preset-flow": "^7.9.0", "@babel/preset-flow": "^7.9.0",
"@babel/preset-react": "^7.9.4", "@babel/preset-react": "^7.9.4",
"@babel/preset-typescript": "^7.9.0", "@babel/preset-typescript": "^7.9.0",
"@babel/runtime": "^7.9.2", "@babel/runtime": "^7.9.6",
"@commitlint/config-conventional": "^8.3.4", "@commitlint/config-conventional": "^8.3.4",
"@types/jest": "^25.2.1", "@types/jest": "^25.2.1",
"babel-jest": "^25.2.6", "babel-jest": "^26.0.1",
"codecov": "^3.6.5", "codecov": "^3.6.5",
"commitlint": "^8.3.5", "commitlint": "^8.3.5",
"core-js": "^3.6.4", "core-js": "^3.6.5",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-config-satya164": "^3.1.6", "eslint-config-satya164": "^3.1.7",
"husky": "^4.2.3", "husky": "^4.2.5",
"jest": "^25.2.7", "jest": "^26.0.1",
"lerna": "^3.20.2", "lerna": "^3.20.2",
"prettier": "^2.0.4", "prettier": "^2.0.5",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },
"resolutions": { "resolutions": {

View File

@@ -3,6 +3,44 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.4.2](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.1...@react-navigation/bottom-tabs@5.4.2) (2020-05-10)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.4.1](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.0...@react-navigation/bottom-tabs@5.4.1) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
# [5.4.0](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.3.4...@react-navigation/bottom-tabs@5.4.0) (2020-05-08)
### Features
* add generic type aliases for screen props ([bea14aa](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/commit/bea14aa26fd5cbfebc7973733c5cf1f44fd323aa)), closes [#7971](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/issues/7971)
## [5.3.4](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.3.3...@react-navigation/bottom-tabs@5.3.4) (2020-05-05)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.3.2...@react-navigation/bottom-tabs@5.3.3) (2020-05-01) ## [5.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.3.2...@react-navigation/bottom-tabs@5.3.3) (2020-05-01)
**Note:** Version bump only for package @react-navigation/bottom-tabs **Note:** Version bump only for package @react-navigation/bottom-tabs

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/bottom-tabs", "name": "@react-navigation/bottom-tabs",
"description": "Bottom tab navigator following iOS design guidelines", "description": "Bottom tab navigator following iOS design guidelines",
"version": "5.3.3", "version": "5.4.2",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -15,6 +15,7 @@
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs", "repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -34,16 +35,16 @@
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.2.1"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@react-navigation/native": "^5.2.3", "@react-navigation/native": "^5.3.0",
"@types/color": "^3.0.1", "@types/color": "^3.0.1",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0", "react-native-screens": "^2.7.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -15,6 +15,7 @@ export { default as BottomTabBar } from './views/BottomTabBar';
export type { export type {
BottomTabNavigationOptions, BottomTabNavigationOptions,
BottomTabNavigationProp, BottomTabNavigationProp,
BottomTabScreenProps,
BottomTabBarProps, BottomTabBarProps,
BottomTabBarOptions, BottomTabBarOptions,
} from './types'; } from './types';

View File

@@ -13,6 +13,7 @@ import {
Descriptor, Descriptor,
TabNavigationState, TabNavigationState,
TabActionHelpers, TabActionHelpers,
RouteProp,
} from '@react-navigation/native'; } from '@react-navigation/native';
export type BottomTabNavigationEventMap = { export type BottomTabNavigationEventMap = {
@@ -45,6 +46,14 @@ export type BottomTabNavigationProp<
> & > &
TabActionHelpers<ParamList>; TabActionHelpers<ParamList>;
export type BottomTabScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = {
navigation: BottomTabNavigationProp<ParamList, RouteName>;
route: RouteProp<ParamList, RouteName>;
};
export type BottomTabNavigationOptions = { export type BottomTabNavigationOptions = {
/** /**
* Title text for the screen. * Title text for the screen.

View File

@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.18](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.17...@react-navigation/compat@5.1.18) (2020-05-10)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.17](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.16...@react-navigation/compat@5.1.17) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
## [5.1.16](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.15...@react-navigation/compat@5.1.16) (2020-05-08)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.15](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.14...@react-navigation/compat@5.1.15) (2020-05-05)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.14](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.13...@react-navigation/compat@5.1.14) (2020-05-01) ## [5.1.14](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.13...@react-navigation/compat@5.1.14) (2020-05-01)
**Note:** Version bump only for package @react-navigation/compat **Note:** Version bump only for package @react-navigation/compat

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/compat", "name": "@react-navigation/compat",
"description": "Compatibility layer to write navigator definitions in static configuration format", "description": "Compatibility layer to write navigator definitions in static configuration format",
"version": "5.1.14", "version": "5.1.18",
"license": "MIT", "license": "MIT",
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/compat", "repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/compat",
"bugs": { "bugs": {
@@ -10,6 +10,7 @@
"homepage": "https://reactnavigation.org/docs/compatibility.html", "homepage": "https://reactnavigation.org/docs/compatibility.html",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -25,9 +26,9 @@
"clean": "del lib" "clean": "del lib"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@react-navigation/native": "^5.2.3", "@react-navigation/native": "^5.3.0",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"react": "~16.9.0", "react": "~16.9.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -3,6 +3,40 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.5.2](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.5.1...@react-navigation/core@5.5.2) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
## [5.5.1](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.5.0...@react-navigation/core@5.5.1) (2020-05-08)
### Bug Fixes
* avoid cleaning up state when a new navigator is mounted. fixes [#8195](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8195) ([f6d0676](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/f6d06768d3c36d1f5beaffcb660f3c259209f2e7))
# [5.5.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.4.0...@react-navigation/core@5.5.0) (2020-05-05)
### Features
* add support for optional params to linking ([#8196](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8196)) ([fcd1cc6](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/fcd1cc64c151e4941f3f544a54b5048d853821f6))
* support params anywhere in path segement ([#8184](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8184)) ([3999fc2](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/3999fc28365c3a06a17d963c7be7fb7e897f99e0))
# [5.4.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.3.5...@react-navigation/core@5.4.0) (2020-04-30) # [5.4.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.3.5...@react-navigation/core@5.4.0) (2020-04-30)

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/core", "name": "@react-navigation/core",
"description": "Core utilities for building navigators", "description": "Core utilities for building navigators",
"version": "5.4.0", "version": "5.5.2",
"keywords": [ "keywords": [
"react", "react",
"react-native", "react-native",
@@ -15,6 +15,7 @@
"homepage": "https://reactnavigation.org", "homepage": "https://reactnavigation.org",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -29,21 +30,21 @@
"clean": "del lib" "clean": "del lib"
}, },
"dependencies": { "dependencies": {
"@react-navigation/routers": "^5.4.2", "@react-navigation/routers": "^5.4.4",
"escape-string-regexp": "^2.0.0", "escape-string-regexp": "^4.0.0",
"nanoid": "^3.0.2", "nanoid": "^3.1.5",
"query-string": "^6.12.0", "query-string": "^6.12.1",
"react-is": "^16.13.0", "react-is": "^16.13.0",
"use-subscription": "^1.4.0" "use-subscription": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-is": "^16.7.1", "@types/react-is": "^16.7.1",
"@types/use-subscription": "^1.0.0", "@types/use-subscription": "^1.0.0",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native-testing-library": "^1.12.0", "react-native-testing-library": "^1.13.2",
"react-test-renderer": "~16.13.1", "react-test-renderer": "~16.13.1",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -984,3 +984,796 @@ it('handles not taking path with too many segments', () => {
state state
); );
}); });
it('handles differently ordered params v1', () => {
const path = '/foos/5/res/20';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foos/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/res/:pwd',
parse: {
id: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, pwd: 20 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handles differently ordered params v2', () => {
const path = '/5/20/foos/res';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foos/:id',
parse: {
id: Number,
},
},
Bas: {
path: ':id/:pwd/foos/res',
parse: {
id: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, pwd: 20 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handles differently ordered params v3', () => {
const path = '/foos/5/20/res';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foos/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:pwd/res',
parse: {
id: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, pwd: 20 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handles differently ordered params v4', () => {
const path = '5/foos/res/20';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foos/:id',
parse: {
id: Number,
},
},
Bas: {
path: ':id/foos/res/:pwd',
parse: {
id: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, pwd: 20 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handles simple optional params', () => {
const path = '/foos/5';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?',
parse: {
id: Number,
nip: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle 2 optional params at the end v1', () => {
const path = '/foos/5';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?/:pwd?',
parse: {
id: Number,
nip: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle 2 optional params at the end v2', () => {
const path = '/foos/5/10';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?/:pwd?',
parse: {
id: Number,
nip: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, nip: 10 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle 2 optional params at the end v3', () => {
const path = '/foos/5/10/15';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?/:pwd?',
parse: {
id: Number,
nip: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, nip: 10, pwd: 15 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the middle v1', () => {
const path = '/foos/5/10';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?/:pwd',
parse: {
id: Number,
nip: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, pwd: 10 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the middle v2', () => {
const path = '/foos/5/10/15';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?/:pwd',
parse: {
id: Number,
nip: Number,
pwd: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, nip: 10, pwd: 15 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the middle v3', () => {
const path = '/foos/5/10/15';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:id/:nip?/:pwd/:smh',
parse: {
id: Number,
nip: Number,
pwd: Number,
smh: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { id: 5, pwd: 10, smh: 15 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the middle v4', () => {
const path = '/foos/5/10';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:nip?/:pwd/:smh?/:id',
parse: {
id: Number,
nip: Number,
pwd: Number,
smh: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { pwd: 5, id: 10 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the middle v5', () => {
const path = '/foos/5/10/15';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: 'foos/:nip?/:pwd/:smh?/:id',
parse: {
id: Number,
nip: Number,
pwd: Number,
smh: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { nip: 5, pwd: 10, id: 15 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the beginning v1', () => {
const path = '5/10/foos/15';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: ':nip?/:pwd/foos/:smh?/:id',
parse: {
id: Number,
nip: Number,
pwd: Number,
smh: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { nip: 5, pwd: 10, id: 15 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});
it('handle optional params in the beginning v2', () => {
const path = '5/10/foos/15';
const config = {
Foe: {
path: '/',
initialRouteName: 'Foo',
screens: {
Foo: 'foo',
Bis: {
path: 'foo/:id',
parse: {
id: Number,
},
},
Bas: {
path: ':nip?/:smh?/:pwd/foos/:id',
parse: {
id: Number,
nip: Number,
pwd: Number,
smh: Number,
},
},
},
},
};
const state = {
routes: [
{
name: 'Foe',
state: {
index: 1,
routes: [
{
name: 'Foo',
},
{
name: 'Bas',
params: { nip: 5, pwd: 10, id: 15 },
},
],
},
},
],
};
expect(getStateFromPath(path, config)).toEqual(state);
expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(
state
);
});

View File

@@ -379,6 +379,8 @@ it("doesn't update state if action wasn't handled", () => {
}); });
it('cleans up state when the navigator unmounts', () => { it('cleans up state when the navigator unmounts', () => {
jest.useFakeTimers();
const TestNavigator = (props: any) => { const TestNavigator = (props: any) => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props); const { state, descriptors } = useNavigationBuilder(MockRouter, props);
@@ -426,6 +428,8 @@ it('cleans up state when the navigator unmounts', () => {
<BaseNavigationContainer onStateChange={onStateChange} children={null} /> <BaseNavigationContainer onStateChange={onStateChange} children={null} />
); );
act(() => jest.runAllTimers());
expect(onStateChange).toBeCalledTimes(2); expect(onStateChange).toBeCalledTimes(2);
expect(onStateChange).lastCalledWith(undefined); expect(onStateChange).lastCalledWith(undefined);
}); });

View File

@@ -135,7 +135,7 @@ export default function getPathFromState(
path += pattern path += pattern
.split('/') .split('/')
.map((p) => { .map((p) => {
const name = p.replace(/^:/, ''); const name = p.replace(/^:/, '').replace(/\?$/, '');
// If the path has a pattern for a param, put the param in the path // If the path has a pattern for a param, put the param in the path
if (params && name in params && p.startsWith(':')) { if (params && name in params && p.startsWith(':')) {
@@ -144,8 +144,10 @@ export default function getPathFromState(
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete params[name]; delete params[name];
return encodeURIComponent(value); return encodeURIComponent(value);
} else if (p.endsWith('?')) {
// optional params without value assigned in route.params should be ignored
return '';
} }
return encodeURIComponent(p); return encodeURIComponent(p);
}) })
.join('/'); .join('/');
@@ -173,7 +175,7 @@ export default function getPathFromState(
} }
// Remove multiple as well as trailing slashes // Remove multiple as well as trailing slashes
path = path.replace(/\/+/, '/'); path = path.replace(/\/+/g, '/');
path = path.length > 1 ? path.replace(/\/$/, '') : path; path = path.length > 1 ? path.replace(/\/$/, '') : path;
return path; return path;

View File

@@ -1,3 +1,4 @@
import escape from 'escape-string-regexp';
import queryString from 'query-string'; import queryString from 'query-string';
import { import {
NavigationState, NavigationState,
@@ -20,7 +21,7 @@ type Options = {
type RouteConfig = { type RouteConfig = {
screen: string; screen: string;
match: string | null; match: RegExp | null;
pattern: string; pattern: string;
routeNames: string[]; routeNames: string[];
parse: ParseConfig | undefined; parse: ParseConfig | undefined;
@@ -74,11 +75,14 @@ export default function getStateFromPath(
); );
let remaining = path let remaining = path
.replace(/[/]+/, '/') // Replace multiple slash (//) with single ones .replace(/\/+/g, '/') // Replace multiple slash (//) with single ones
.replace(/^\//, '') // Remove extra leading slash .replace(/^\//, '') // Remove extra leading slash
.replace(/\?.*/, ''); // Remove query params which we will handle later .replace(/\?.*$/, ''); // Remove query params which we will handle later
if (remaining === '') { // Make sure there is a trailing slash
remaining = remaining.endsWith('/') ? remaining : `${remaining}/`;
if (remaining === '/') {
// We need to add special handling of empty path so navigation to empty path also works // We need to add special handling of empty path so navigation to empty path also works
// When handling empty path, we should only look at the root level config // When handling empty path, we should only look at the root level config
const match = configs.find( const match = configs.find(
@@ -114,27 +118,10 @@ export default function getStateFromPath(
continue; continue;
} }
let didMatch = true; const match = remaining.match(config.match);
const matchParts = config.match.split('/');
const remainingParts = remaining.split('/');
// we check if remaining path has enough segments to be handled with this pattern // If our regex matches, we need to extract params from the path
if (config.pattern.split('/').length > remainingParts.length) { if (match) {
continue;
}
// we keep info about the index of segment on which the params start
let paramsIndex = 0;
// the beginning of the remaining path should be the same as the part of config before params
for (paramsIndex; paramsIndex < matchParts.length; paramsIndex++) {
if (matchParts[paramsIndex] !== remainingParts[paramsIndex]) {
didMatch = false;
break;
}
}
// If the first part of the path matches, we need to extract params from the path
if (didMatch) {
routeNames = [...config.routeNames]; routeNames = [...config.routeNames];
const paramPatterns = config.pattern const paramPatterns = config.pattern
@@ -143,27 +130,21 @@ export default function getStateFromPath(
if (paramPatterns.length) { if (paramPatterns.length) {
params = paramPatterns.reduce<Record<string, any>>((acc, p, i) => { params = paramPatterns.reduce<Record<string, any>>((acc, p, i) => {
const key = p.replace(/^:/, ''); const key = p.replace(/^:/, '').replace(/\?$/, '');
const value = remainingParts[i + paramsIndex]; // The param segments start from the end of matched part const value = match[(i + 1) * 2].replace(/\//, ''); // The param segments appear every second item starting from 2 in the regex match result
if (value) {
acc[key] = acc[key] =
config.parse && config.parse[key] config.parse && config.parse[key]
? config.parse[key](value) ? config.parse[key](value)
: value; : value;
}
return acc; return acc;
}, {}); }, {});
} }
// if pattern and remaining path have same amount of segments, there should be nothing left remaining = remaining.replace(match[1], '');
if (config.pattern.split('/').length === remainingParts.length) {
remaining = '';
} else {
// For each segment of the pattern, remove one segment from remaining path
let i = config.pattern.split('/').length;
while (i--) {
remaining = remaining.substr(remaining.indexOf('/') + 1);
}
}
break; break;
} }
@@ -267,8 +248,20 @@ function createConfigItem(
pattern: string, pattern: string,
parse?: ParseConfig parse?: ParseConfig
): RouteConfig { ): RouteConfig {
// part being matched ends on the first param const match = pattern
const match = pattern !== '' ? pattern.split('/:')[0] : null; ? new RegExp(
`^(${pattern
.split('/')
.map((it) => {
if (it.startsWith(':')) {
return `(([^/]+\\/)${it.endsWith('?') ? '?' : ''})`;
}
return `${escape(it)}\\/`;
})
.join('')})`
)
: null;
return { return {
screen, screen,

View File

@@ -9,6 +9,7 @@ import useNavigation from './useNavigation';
*/ */
export default function useIsFocused(): boolean { export default function useIsFocused(): boolean {
const navigation = useNavigation(); const navigation = useNavigation();
// eslint-disable-next-line react-hooks/exhaustive-deps
const getCurrentValue = React.useCallback(navigation.isFocused, [navigation]); const getCurrentValue = React.useCallback(navigation.isFocused, [navigation]);
const subscribe = React.useCallback( const subscribe = React.useCallback(
(callback: (value: boolean) => void) => { (callback: (value: boolean) => void) => {

View File

@@ -362,9 +362,14 @@ export default function useNavigationBuilder<
return () => { return () => {
// We need to clean up state for this navigator on unmount // We need to clean up state for this navigator on unmount
// We do it in a timeout because we need to detect if another navigator mounted in the meantime
// For example, if another navigator has started rendering, we should skip cleanup
// Otherwise, our cleanup step will cleanup state for the other navigator and re-initialize it
setTimeout(() => {
if (getCurrentState() !== undefined && getKey() === navigatorKey) { if (getCurrentState() !== undefined && getKey() === navigatorKey) {
setState(undefined); setState(undefined);
} }
}, 0);
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);

View File

@@ -3,6 +3,44 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.7.2](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.1...@react-navigation/drawer@5.7.2) (2020-05-10)
**Note:** Version bump only for package @react-navigation/drawer
## [5.7.1](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.0...@react-navigation/drawer@5.7.1) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
# [5.7.0](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.6.4...@react-navigation/drawer@5.7.0) (2020-05-08)
### Features
* add generic type aliases for screen props ([bea14aa](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/bea14aa26fd5cbfebc7973733c5cf1f44fd323aa)), closes [#7971](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/issues/7971)
## [5.6.4](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.6.3...@react-navigation/drawer@5.6.4) (2020-05-05)
**Note:** Version bump only for package @react-navigation/drawer
## [5.6.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.6.2...@react-navigation/drawer@5.6.3) (2020-05-01) ## [5.6.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.6.2...@react-navigation/drawer@5.6.3) (2020-05-01)
**Note:** Version bump only for package @react-navigation/drawer **Note:** Version bump only for package @react-navigation/drawer

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/drawer", "name": "@react-navigation/drawer",
"description": "Drawer navigator component with animated transitions and gesturess", "description": "Drawer navigator component with animated transitions and gesturess",
"version": "5.6.3", "version": "5.7.2",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -20,6 +20,7 @@
"homepage": "https://reactnavigation.org/docs/drawer-navigator.html", "homepage": "https://reactnavigation.org/docs/drawer-navigator.html",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -39,17 +40,17 @@
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.2.1"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@react-navigation/native": "^5.2.3", "@react-navigation/native": "^5.3.0",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0", "react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0", "react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0", "react-native-screens": "^2.7.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -25,6 +25,7 @@ export { default as useIsDrawerOpen } from './utils/useIsDrawerOpen';
export type { export type {
DrawerNavigationOptions, DrawerNavigationOptions,
DrawerNavigationProp, DrawerNavigationProp,
DrawerScreenProps,
DrawerContentOptions, DrawerContentOptions,
DrawerContentComponentProps, DrawerContentComponentProps,
} from './types'; } from './types';

View File

@@ -8,6 +8,7 @@ import {
NavigationHelpers, NavigationHelpers,
DrawerNavigationState, DrawerNavigationState,
DrawerActionHelpers, DrawerActionHelpers,
RouteProp,
} from '@react-navigation/native'; } from '@react-navigation/native';
import type { PanGestureHandlerProperties } from 'react-native-gesture-handler'; import type { PanGestureHandlerProperties } from 'react-native-gesture-handler';
@@ -208,6 +209,14 @@ export type DrawerNavigationProp<
> & > &
DrawerActionHelpers<ParamList>; DrawerActionHelpers<ParamList>;
export type DrawerScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = {
navigation: DrawerNavigationProp<ParamList, RouteName>;
route: RouteProp<ParamList, RouteName>;
};
export type DrawerDescriptor = Descriptor< export type DrawerDescriptor = Descriptor<
ParamListBase, ParamListBase,
string, string,

View File

@@ -655,14 +655,14 @@ export default class DrawerView extends React.Component<Props> {
gestureEnabled ? () => this.toggleDrawer(false) : undefined gestureEnabled ? () => this.toggleDrawer(false) : undefined
} }
> >
<Overlay progress={progress} style={overlayStyle} /> <Overlay progress={progress} style={overlayStyle as any} />
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
) : ( ) : (
<TapGestureHandler <TapGestureHandler
enabled={gestureEnabled} enabled={gestureEnabled}
onHandlerStateChange={this.handleTapStateChange} onHandlerStateChange={this.handleTapStateChange}
> >
<Overlay progress={progress} style={overlayStyle} /> <Overlay progress={progress} style={overlayStyle as any} />
</TapGestureHandler> </TapGestureHandler>
) )
} }

View File

@@ -3,6 +3,45 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.2.2](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.1...@react-navigation/material-bottom-tabs@5.2.2) (2020-05-10)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.2.1](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.0...@react-navigation/material-bottom-tabs@5.2.1) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
# [5.2.0](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.15...@react-navigation/material-bottom-tabs@5.2.0) (2020-05-08)
### Features
* add generic type aliases for screen props ([bea14aa](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/commit/bea14aa26fd5cbfebc7973733c5cf1f44fd323aa)), closes [#7971](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/issues/7971)
* use links in bottom navigation tabs ([f384706](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/commit/f384706741f7e2422c284b65da10425f7af680c0))
## [5.1.15](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.14...@react-navigation/material-bottom-tabs@5.1.15) (2020-05-05)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.1.14](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.13...@react-navigation/material-bottom-tabs@5.1.14) (2020-05-01) ## [5.1.14](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.13...@react-navigation/material-bottom-tabs@5.1.14) (2020-05-01)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs **Note:** Version bump only for package @react-navigation/material-bottom-tabs

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/material-bottom-tabs", "name": "@react-navigation/material-bottom-tabs",
"description": "Integration for bottom navigation component from react-native-paper", "description": "Integration for bottom navigation component from react-native-paper",
"version": "5.1.14", "version": "5.2.2",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -20,6 +20,7 @@
"homepage": "https://reactnavigation.org/docs/material-bottom-tab-navigator.html", "homepage": "https://reactnavigation.org/docs/material-bottom-tab-navigator.html",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -35,15 +36,15 @@
"clean": "del lib" "clean": "del lib"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@react-navigation/native": "^5.2.3", "@react-navigation/native": "^5.3.0",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.62.7",
"@types/react-native-vector-icons": "^6.4.5", "@types/react-native-vector-icons": "^6.4.5",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-paper": "^3.7.0", "react-native-paper": "^3.10.1",
"react-native-vector-icons": "^6.6.0", "react-native-vector-icons": "^6.6.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -14,4 +14,5 @@ export { default as MaterialBottomTabView } from './views/MaterialBottomTabView'
export type { export type {
MaterialBottomTabNavigationOptions, MaterialBottomTabNavigationOptions,
MaterialBottomTabNavigationProp, MaterialBottomTabNavigationProp,
MaterialBottomTabScreenProps,
} from './types'; } from './types';

View File

@@ -6,6 +6,7 @@ import {
NavigationHelpers, NavigationHelpers,
TabNavigationState, TabNavigationState,
TabActionHelpers, TabActionHelpers,
RouteProp,
} from '@react-navigation/native'; } from '@react-navigation/native';
export type MaterialBottomTabNavigationEventMap = { export type MaterialBottomTabNavigationEventMap = {
@@ -32,6 +33,14 @@ export type MaterialBottomTabNavigationProp<
> & > &
TabActionHelpers<ParamList>; TabActionHelpers<ParamList>;
export type MaterialBottomTabScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = {
navigation: MaterialBottomTabNavigationProp<ParamList, RouteName>;
route: RouteProp<ParamList, RouteName>;
};
export type MaterialBottomTabNavigationOptions = { export type MaterialBottomTabNavigationOptions = {
/** /**
* Title text for the screen. * Title text for the screen.

View File

@@ -1,5 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import { StyleSheet } from 'react-native'; import { StyleSheet, Platform } from 'react-native';
import { BottomNavigation, DefaultTheme, DarkTheme } from 'react-native-paper'; import { BottomNavigation, DefaultTheme, DarkTheme } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { import {
@@ -8,6 +8,8 @@ import {
TabNavigationState, TabNavigationState,
TabActions, TabActions,
useTheme, useTheme,
useLinkBuilder,
Link,
} from '@react-navigation/native'; } from '@react-navigation/native';
import { import {
@@ -24,13 +26,14 @@ type Props = MaterialBottomTabNavigationConfig & {
type Scene = { route: { key: string } }; type Scene = { route: { key: string } };
export default function MaterialBottomTabView({ function MaterialBottomTabViewInner({
state, state,
navigation, navigation,
descriptors, descriptors,
...rest ...rest
}: Props) { }: Props) {
const { dark, colors } = useTheme(); const { dark, colors } = useTheme();
const buildLink = useLinkBuilder();
const theme = React.useMemo(() => { const theme = React.useMemo(() => {
const t = dark ? DarkTheme : DefaultTheme; const t = dark ? DarkTheme : DefaultTheme;
@@ -46,7 +49,6 @@ export default function MaterialBottomTabView({
}, [colors, dark]); }, [colors, dark]);
return ( return (
<NavigationHelpersContext.Provider value={navigation}>
<BottomNavigation <BottomNavigation
{...rest} {...rest}
theme={theme} theme={theme}
@@ -58,6 +60,37 @@ export default function MaterialBottomTabView({
}) })
} }
renderScene={({ route }) => descriptors[route.key].render()} renderScene={({ route }) => descriptors[route.key].render()}
renderTouchable={
Platform.OS === 'web'
? ({
onPress,
route,
accessibilityRole: _0,
borderless: _1,
centered: _2,
rippleColor: _3,
...rest
}) => {
return (
<Link
{...rest}
// @ts-ignore
to={buildLink(route.name, route.params)}
accessibilityRole="link"
onPress={(e: any) => {
if (
!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
(e.button == null || e.button === 0) // ignore everything but left clicks
) {
e.preventDefault();
onPress?.(e);
}
}}
/>
);
}
: undefined
}
renderIcon={({ route, focused, color }) => { renderIcon={({ route, focused, color }) => {
const { options } = descriptors[route.key]; const { options } = descriptors[route.key];
@@ -68,8 +101,6 @@ export default function MaterialBottomTabView({
color={color} color={color}
size={24} size={24}
style={styles.icon} style={styles.icon}
importantForAccessibility="no-hide-descendants"
accessibilityElementsHidden
/> />
); );
} }
@@ -107,6 +138,13 @@ export default function MaterialBottomTabView({
} }
}} }}
/> />
);
}
export default function MaterialBottomTabView(props: Props) {
return (
<NavigationHelpersContext.Provider value={props.navigation}>
<MaterialBottomTabViewInner {...props} />
</NavigationHelpersContext.Provider> </NavigationHelpersContext.Provider>
); );
} }

View File

@@ -3,6 +3,44 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.2.2](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.1...@react-navigation/material-top-tabs@5.2.2) (2020-05-10)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.1](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.0...@react-navigation/material-top-tabs@5.2.1) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
# [5.2.0](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.15...@react-navigation/material-top-tabs@5.2.0) (2020-05-08)
### Features
* add generic type aliases for screen props ([bea14aa](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/commit/bea14aa26fd5cbfebc7973733c5cf1f44fd323aa)), closes [#7971](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/issues/7971)
## [5.1.15](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.14...@react-navigation/material-top-tabs@5.1.15) (2020-05-05)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.1.14](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.13...@react-navigation/material-top-tabs@5.1.14) (2020-05-01) ## [5.1.14](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.13...@react-navigation/material-top-tabs@5.1.14) (2020-05-01)
**Note:** Version bump only for package @react-navigation/material-top-tabs **Note:** Version bump only for package @react-navigation/material-top-tabs

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/material-top-tabs", "name": "@react-navigation/material-top-tabs",
"description": "Integration for the animated tab view component from react-native-tab-view", "description": "Integration for the animated tab view component from react-native-tab-view",
"version": "5.1.14", "version": "5.2.2",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -20,6 +20,7 @@
"homepage": "https://reactnavigation.org/docs/material-top-tab-navigator.html", "homepage": "https://reactnavigation.org/docs/material-top-tab-navigator.html",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -38,15 +39,15 @@
"color": "^3.1.2" "color": "^3.1.2"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@react-navigation/native": "^5.2.3", "@react-navigation/native": "^5.3.0",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0", "react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0", "react-native-reanimated": "^1.8.0",
"react-native-tab-view": "^2.14.0", "react-native-tab-view": "^2.14.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -15,6 +15,7 @@ export { default as MaterialTopTabBar } from './views/MaterialTopTabBar';
export type { export type {
MaterialTopTabNavigationOptions, MaterialTopTabNavigationOptions,
MaterialTopTabNavigationProp, MaterialTopTabNavigationProp,
MaterialTopTabScreenProps,
MaterialTopTabBarProps, MaterialTopTabBarProps,
MaterialTopTabBarOptions, MaterialTopTabBarOptions,
} from './types'; } from './types';

View File

@@ -8,6 +8,7 @@ import {
NavigationProp, NavigationProp,
TabNavigationState, TabNavigationState,
TabActionHelpers, TabActionHelpers,
RouteProp,
} from '@react-navigation/native'; } from '@react-navigation/native';
export type MaterialTopTabNavigationEventMap = { export type MaterialTopTabNavigationEventMap = {
@@ -46,6 +47,14 @@ export type MaterialTopTabNavigationProp<
> & > &
TabActionHelpers<ParamList>; TabActionHelpers<ParamList>;
export type MaterialTopTabScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = {
navigation: MaterialTopTabNavigationProp<ParamList, RouteName>;
route: RouteProp<ParamList, RouteName>;
};
export type MaterialTopTabNavigationOptions = { export type MaterialTopTabNavigationOptions = {
/** /**
* Title text for the screen. * Title text for the screen.

View File

@@ -3,6 +3,50 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.3.0](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.2.6...@react-navigation/native@5.3.0) (2020-05-10)
### Features
* initialState should take priority over deep link ([039017b](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/039017bc2af69120d2d10e8f2c8a62919c37eb65))
## [5.2.6](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.2.5...@react-navigation/native@5.2.6) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/native/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
## [5.2.5](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.2.4...@react-navigation/native@5.2.5) (2020-05-08)
### Bug Fixes
* return a promise-like from getInitialState ([#8210](https://github.com/react-navigation/react-navigation/tree/master/packages/native/issues/8210)) ([85ae378](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/85ae378d8cb1073895b281e13ebccee881d4c062))
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.2.3...@react-navigation/native@5.2.4) (2020-05-05)
### Bug Fixes
* return undefined for buildLink if linking is not enabled ([9fd2635](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/9fd2635756362c8da79656b4d9b101bebaaf7003))
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.2.2...@react-navigation/native@5.2.3) (2020-05-01) ## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.2.2...@react-navigation/native@5.2.3) (2020-05-01)

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/native", "name": "@react-navigation/native",
"description": "React Native integration for React Navigation", "description": "React Native integration for React Navigation",
"version": "5.2.3", "version": "5.3.0",
"keywords": [ "keywords": [
"react-native", "react-native",
"react-navigation", "react-navigation",
@@ -16,6 +16,7 @@
"homepage": "https://reactnavigation.org", "homepage": "https://reactnavigation.org",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -31,16 +32,16 @@
"clean": "del lib" "clean": "del lib"
}, },
"dependencies": { "dependencies": {
"@react-navigation/core": "^5.4.0" "@react-navigation/core": "^5.5.2"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-testing-library": "^1.12.0", "react-native-testing-library": "^1.13.2",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -22,7 +22,7 @@ type Props = NavigationContainerProps & {
* Container component which holds the navigation state designed for React Native apps. * Container component which holds the navigation state designed for React Native apps.
* This should be rendered at the root wrapping the whole app. * This should be rendered at the root wrapping the whole app.
* *
* @param props.initialState Initial state object for the navigation tree. When deep link handling is enabled, this will be ignored if there's an incoming link. * @param props.initialState Initial state object for the navigation tree. When deep link handling is enabled, this will override deep links when specified. Make sure that you don't specify an `initialState` when there's a deep link (`Linking.getInitialURL()`).
* @param props.onStateChange Callback which is called with the latest navigation state when it changes. * @param props.onStateChange Callback which is called with the latest navigation state when it changes.
* @param props.theme Theme object for the navigators. * @param props.theme Theme object for the navigators.
* @param props.linking Options for deep linking. Deep link handling is enabled when this prop is provided, unless `linking.enabled` is `false`. * @param props.linking Options for deep linking. Deep link handling is enabled when this prop is provided, unless `linking.enabled` is `false`.
@@ -46,15 +46,13 @@ const NavigationContainer = React.forwardRef(function NavigationContainer(
...linking, ...linking,
}); });
const [isReady, initialState = rest.initialState] = useThenable( const [isReady, initialState] = useThenable(getInitialState);
getInitialState
);
React.useImperativeHandle(ref, () => refContainer.current); React.useImperativeHandle(ref, () => refContainer.current);
const linkingContext = React.useMemo(() => ({ options: linking }), [linking]); const linkingContext = React.useMemo(() => ({ options: linking }), [linking]);
if (isLinkingEnabled && !isReady) { if (rest.initialState == null && isLinkingEnabled && !isReady) {
// This is temporary until we have Suspense for data-fetching // This is temporary until we have Suspense for data-fetching
// Then the fallback will be handled by a parent `Suspense` component // Then the fallback will be handled by a parent `Suspense` component
return fallback as React.ReactElement; return fallback as React.ReactElement;
@@ -65,7 +63,9 @@ const NavigationContainer = React.forwardRef(function NavigationContainer(
<ThemeProvider value={theme}> <ThemeProvider value={theme}>
<BaseNavigationContainer <BaseNavigationContainer
{...rest} {...rest}
initialState={initialState} initialState={
rest.initialState == null ? initialState : rest.initialState
}
ref={refContainer} ref={refContainer}
/> />
</ThemeProvider> </ThemeProvider>

View File

@@ -52,14 +52,18 @@ export default function useLinkBuilder() {
(name: string, params?: object) => { (name: string, params?: object) => {
const { options } = linking; const { options } = linking;
// If we couldn't find a navigation object in context, we're at root if (options?.enabled === false) {
// So we'll construct a basic state object to use return undefined;
}
const state = navigation const state = navigation
? getRootStateForNavigate(navigation, { ? getRootStateForNavigate(navigation, {
index: 0, index: 0,
routes: [{ name, params }], routes: [{ name, params }],
}) })
: { : // If we couldn't find a navigation object in context, we're at root
// So we'll construct a basic state object to use
{
index: 0, index: 0,
routes: [{ name, params }], routes: [{ name, params }],
}; };

View File

@@ -49,6 +49,14 @@ export default function useLinkProps({ to, action }: Props) {
throw new Error("Couldn't find a navigation object."); throw new Error("Couldn't find a navigation object.");
} }
} else { } else {
if (typeof to !== 'string') {
throw new Error(
`To 'to' option is invalid (found '${String(
to
)}'. It must be a valid string for navigation.`
);
}
linkTo(to); linkTo(to);
} }
} }

View File

@@ -95,18 +95,17 @@ export default function useLinking(
} }
} }
const then = (callback: (state: ResultState | undefined) => void) =>
Promise.resolve(callback(value));
// Make it a thenable to keep consistent with the native impl // Make it a thenable to keep consistent with the native impl
const thenable = { const thenable = {
then, then(onfulfilled?: (state: ResultState | undefined) => void) {
return Promise.resolve(onfulfilled ? onfulfilled(value) : value);
},
catch() { catch() {
return thenable; return thenable;
}, },
}; };
return thenable; return thenable as PromiseLike<ResultState | undefined>;
}, []); }, []);
const previousStateLengthRef = React.useRef<number | undefined>(undefined); const previousStateLengthRef = React.useRef<number | undefined>(undefined);

View File

@@ -1,8 +1,6 @@
import * as React from 'react'; import * as React from 'react';
type Thenable<T> = { then(cb: (result: T) => void): void }; export default function useThenable<T>(create: () => PromiseLike<T>) {
export default function useThenable<T>(create: () => Thenable<T>) {
const [promise] = React.useState(create); const [promise] = React.useState(create);
// Check if our thenable is synchronous // Check if our thenable is synchronous

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.4.4](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.3...@react-navigation/routers@5.4.4) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
## [5.4.3](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.2...@react-navigation/routers@5.4.3) (2020-05-08)
**Note:** Version bump only for package @react-navigation/routers
## [5.4.2](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.1...@react-navigation/routers@5.4.2) (2020-04-30) ## [5.4.2](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.1...@react-navigation/routers@5.4.2) (2020-04-30)

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/routers", "name": "@react-navigation/routers",
"description": "Routers to help build custom navigators", "description": "Routers to help build custom navigators",
"version": "5.4.2", "version": "5.4.4",
"keywords": [ "keywords": [
"react", "react",
"react-native", "react-native",
@@ -15,6 +15,7 @@
"homepage": "https://reactnavigation.org/docs/custom-routers.html", "homepage": "https://reactnavigation.org/docs/custom-routers.html",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -30,10 +31,10 @@
"clean": "del lib" "clean": "del lib"
}, },
"dependencies": { "dependencies": {
"nanoid": "^3.0.2" "nanoid": "^3.1.5"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -3,6 +3,61 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.2...@react-navigation/stack@5.3.3) (2020-05-11)
### Bug Fixes
* fix ios transitionspec settle time ([#8028](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/8028)) ([dd7cff2](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/dd7cff201608365a80f1d50a006df3e0d18e94a1))
## [5.3.2](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.1...@react-navigation/stack@5.3.2) (2020-05-10)
**Note:** Version bump only for package @react-navigation/stack
## [5.3.1](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.0...@react-navigation/stack@5.3.1) (2020-05-08)
### Bug Fixes
* fix building typescript definitions. closes [#8216](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/8216) ([47a1229](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/47a12298378747edd2d22e54dc1c8677f98c49b4))
# [5.3.0](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.19...@react-navigation/stack@5.3.0) (2020-05-08)
### Bug Fixes
* add proper margins to the header title ([f07cd13](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/f07cd135619d635e8841aa0df0b6e687636e7408))
* include safe are insets in title's margins ([4d1e102](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/4d1e102f8c3ffab116d0195fbab3086f6345a077))
### Features
* add generic type aliases for screen props ([bea14aa](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/bea14aa26fd5cbfebc7973733c5cf1f44fd323aa)), closes [#7971](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7971)
## [5.2.19](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.18...@react-navigation/stack@5.2.19) (2020-05-05)
**Note:** Version bump only for package @react-navigation/stack
## [5.2.18](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.17...@react-navigation/stack@5.2.18) (2020-05-01) ## [5.2.18](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.17...@react-navigation/stack@5.2.18) (2020-05-01)
**Note:** Version bump only for package @react-navigation/stack **Note:** Version bump only for package @react-navigation/stack

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/stack", "name": "@react-navigation/stack",
"description": "Stack navigator component for iOS and Android with animated transitions and gestures", "description": "Stack navigator component for iOS and Android with animated transitions and gestures",
"version": "5.2.18", "version": "5.3.3",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -19,6 +19,7 @@
"homepage": "https://reactnavigation.org/docs/stack-navigator.html", "homepage": "https://reactnavigation.org/docs/stack-navigator.html",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"react-native": "src/index.tsx", "react-native": "src/index.tsx",
"source": "src/index.tsx",
"module": "lib/module/index.js", "module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
@@ -38,18 +39,18 @@
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.2.1"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.13.1",
"@react-native-community/masked-view": "^0.1.7", "@react-native-community/masked-view": "^0.1.10",
"@react-navigation/native": "^5.2.3", "@react-navigation/native": "^5.3.0",
"@types/color": "^3.0.1", "@types/color": "^3.0.1",
"@types/react": "^16.9.23", "@types/react": "^16.9.34",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0", "react-native-gesture-handler": "^1.6.0",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0", "react-native-screens": "^2.7.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -11,8 +11,8 @@ export const TransitionIOSSpec: TransitionSpec = {
damping: 500, damping: 500,
mass: 3, mass: 3,
overshootClamping: true, overshootClamping: true,
restDisplacementThreshold: 0.01, restDisplacementThreshold: 10,
restSpeedThreshold: 0.01, restSpeedThreshold: 10,
}, },
}; };

View File

@@ -51,6 +51,7 @@ export { default as useGestureHandlerRef } from './utils/useGestureHandlerRef';
export type { export type {
StackNavigationOptions, StackNavigationOptions,
StackNavigationProp, StackNavigationProp,
StackScreenProps,
StackHeaderProps, StackHeaderProps,
StackHeaderLeftButtonProps, StackHeaderLeftButtonProps,
StackHeaderTitleProps, StackHeaderTitleProps,

View File

@@ -15,6 +15,7 @@ import {
NavigationHelpers, NavigationHelpers,
StackNavigationState, StackNavigationState,
StackActionHelpers, StackActionHelpers,
RouteProp,
} from '@react-navigation/native'; } from '@react-navigation/native';
export type StackNavigationEventMap = { export type StackNavigationEventMap = {
@@ -45,6 +46,14 @@ export type StackNavigationProp<
> & > &
StackActionHelpers<ParamList>; StackActionHelpers<ParamList>;
export type StackScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = {
navigation: StackNavigationProp<ParamList, RouteName>;
route: RouteProp<ParamList, RouteName>;
};
export type Layout = { width: number; height: number }; export type Layout = { width: number; height: number };
export type GestureDirection = export type GestureDirection =

View File

@@ -41,6 +41,7 @@ export default React.memo(function Header(props: StackHeaderProps) {
: previous.route.name; : previous.route.name;
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
const goBack = React.useCallback( const goBack = React.useCallback(
debounce(() => { debounce(() => {
if (navigation.isFocused() && navigation.canGoBack()) { if (navigation.isFocused() && navigation.canGoBack()) {

View File

@@ -307,6 +307,8 @@ export default class HeaderSegment extends React.Component<Props, State> {
}) })
: null; : null;
const rightButton = right ? right({ tintColor: headerTintColor }) : null;
return ( return (
<React.Fragment> <React.Fragment>
<Animated.View <Animated.View
@@ -345,8 +347,17 @@ export default class HeaderSegment extends React.Component<Props, State> {
pointerEvents="box-none" pointerEvents="box-none"
style={[ style={[
headerTitleAlign === 'left' headerTitleAlign === 'left'
? { position: 'absolute', left: leftButton ? 72 : 16 } ? {
: { marginHorizontal: 18 }, position: 'absolute',
left: (leftButton ? 72 : 16) + insets.left,
right: (rightButton ? 72 : 16) + insets.right,
}
: {
marginHorizontal:
(leftButton ? 32 : 16) +
(leftLabelLayout?.width || 0) +
Math.max(insets.left, insets.right),
},
titleStyle, titleStyle,
titleContainerStyle, titleContainerStyle,
]} ]}
@@ -359,7 +370,7 @@ export default class HeaderSegment extends React.Component<Props, State> {
style: customTitleStyle, style: customTitleStyle,
})} })}
</Animated.View> </Animated.View>
{right ? ( {rightButton ? (
<Animated.View <Animated.View
pointerEvents="box-none" pointerEvents="box-none"
style={[ style={[
@@ -369,7 +380,7 @@ export default class HeaderSegment extends React.Component<Props, State> {
rightContainerStyle, rightContainerStyle,
]} ]}
> >
{right({ tintColor: headerTintColor })} {rightButton}
</Animated.View> </Animated.View>
) : null} ) : null}
</View> </View>

View File

@@ -2,7 +2,7 @@ import * as React from 'react';
import { Animated, StyleSheet, Platform } from 'react-native'; import { Animated, StyleSheet, Platform } from 'react-native';
import { useTheme } from '@react-navigation/native'; import { useTheme } from '@react-navigation/native';
type Props = React.ComponentProps<typeof Animated.Text> & { type Props = Omit<React.ComponentProps<typeof Animated.Text>, 'key'> & {
tintColor?: string; tintColor?: string;
children?: string; children?: string;
}; };

2455
yarn.lock

File diff suppressed because it is too large Load Diff