mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-15 09:42:27 +08:00
Compare commits
32 Commits
@react-nav
...
@react-nav
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49f658fbc0 | ||
|
|
cb2f157a56 | ||
|
|
c4acdaa703 | ||
|
|
f1a8bceba5 | ||
|
|
44081172d4 | ||
|
|
de5d985f3b | ||
|
|
b71de6cc79 | ||
|
|
303f0b78a5 | ||
|
|
ce3994c82c | ||
|
|
ba1f405129 | ||
|
|
d4fd906915 | ||
|
|
b7fa90bf8d | ||
|
|
9556aa9eff | ||
|
|
9a8fea8f2c | ||
|
|
9973db86f0 | ||
|
|
8432e5ab25 | ||
|
|
9bb5cfded3 | ||
|
|
4ac40b5c5d | ||
|
|
cd47915861 | ||
|
|
d649fbc669 | ||
|
|
105da6ab2f | ||
|
|
ac7f972e92 | ||
|
|
babb5027f9 | ||
|
|
78d7a66b2b | ||
|
|
a248c453ba | ||
|
|
e097df880a | ||
|
|
856449b200 | ||
|
|
d94e43c3c8 | ||
|
|
3096de6286 | ||
|
|
1c001424b5 | ||
|
|
0f2368965c | ||
|
|
61f16d3f25 |
@@ -7,7 +7,7 @@
|
|||||||
"slug": "react-navigation-example",
|
"slug": "react-navigation-example",
|
||||||
"description": "Demo app to showcase various functionality of React Navigation",
|
"description": "Demo app to showcase various functionality of React Navigation",
|
||||||
"privacy": "public",
|
"privacy": "public",
|
||||||
"sdkVersion": "36.0.0",
|
"sdkVersion": "37.0.0",
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"ios",
|
"ios",
|
||||||
"android",
|
"android",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable jest/no-jasmine-globals, import/no-commonjs */
|
/* eslint-disable import/no-commonjs */
|
||||||
|
|
||||||
const detox = require('detox');
|
const detox = require('detox');
|
||||||
const config = require('../../package.json').detox;
|
const config = require('../../package.json').detox;
|
||||||
|
|||||||
@@ -12,31 +12,30 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/vector-icons": "^10.0.0",
|
"@expo/vector-icons": "^10.0.0",
|
||||||
"@react-native-community/masked-view": "0.1.7",
|
"@react-native-community/masked-view": "^0.1.7",
|
||||||
"@types/react-native-restart": "^0.0.0",
|
|
||||||
"color": "^3.1.2",
|
"color": "^3.1.2",
|
||||||
"expo": "^36.0.2",
|
"expo": "^37.0.0",
|
||||||
"expo-asset": "~8.0.0",
|
"expo-asset": "~8.1.3",
|
||||||
"expo-blur": "^8.0.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.6.0",
|
"react-native-paper": "^3.7.0",
|
||||||
"react-native-reanimated": "^1.7.0",
|
"react-native-reanimated": "^1.7.0",
|
||||||
"react-native-restart": "^0.0.14",
|
"react-native-restart": "^0.0.14",
|
||||||
"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.3.0",
|
||||||
"react-native-tab-view": "2.13.0",
|
"react-native-tab-view": "2.14.0",
|
||||||
"react-native-unimodules": "^0.7.0",
|
"react-native-unimodules": "~0.8.1",
|
||||||
"react-native-web": "^0.11.7"
|
"react-native-web": "^0.11.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@expo/webpack-config": "^0.11.7",
|
"@expo/webpack-config": "^0.11.19",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.60.22",
|
||||||
"babel-preset-expo": "^8.0.0",
|
"babel-preset-expo": "^8.1.0",
|
||||||
"expo-cli": "^3.13.8",
|
"expo-cli": "^3.17.18",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const THEME_PERSISTENCE_KEY = 'THEME_TYPE';
|
|||||||
Asset.loadAsync(StackAssets);
|
Asset.loadAsync(StackAssets);
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const containerRef = React.useRef<NavigationContainerRef>();
|
const containerRef = React.useRef<NavigationContainerRef>(null);
|
||||||
|
|
||||||
// To test deep linking on, run the following in the Terminal:
|
// To test deep linking on, run the following in the Terminal:
|
||||||
// Android: adb shell am start -a android.intent.action.VIEW -d "exp://127.0.0.1:19000/--/simple-stack"
|
// Android: adb shell am start -a android.intent.action.VIEW -d "exp://127.0.0.1:19000/--/simple-stack"
|
||||||
|
|||||||
26
package.json
26
package.json
@@ -18,7 +18,7 @@
|
|||||||
"author": "Satyajit Sahoo <satyajit.happy@gmail.com> (https://github.com/satya164/), Michał Osadnik <micosa97@gmail.com> (https://github.com/osdnk/)",
|
"author": "Satyajit Sahoo <satyajit.happy@gmail.com> (https://github.com/satya164/), Michał Osadnik <micosa97@gmail.com> (https://github.com/osdnk/)",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint --ext '.js,.ts,.tsx' .",
|
"lint": "eslint --ext '.js,.ts,.tsx' .",
|
||||||
"typescript": "tsc --noEmit",
|
"typescript": "tsc --noEmit --composite false",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"prerelease": "lerna run clean",
|
"prerelease": "lerna run clean",
|
||||||
"release": "lerna publish",
|
"release": "lerna publish",
|
||||||
@@ -26,25 +26,25 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
||||||
"@babel/preset-env": "^7.8.7",
|
"@babel/preset-env": "^7.9.0",
|
||||||
"@babel/preset-flow": "^7.8.3",
|
"@babel/preset-flow": "^7.9.0",
|
||||||
"@babel/preset-react": "^7.8.3",
|
"@babel/preset-react": "^7.9.4",
|
||||||
"@babel/preset-typescript": "^7.8.3",
|
"@babel/preset-typescript": "^7.9.0",
|
||||||
"@babel/runtime": "^7.8.7",
|
"@babel/runtime": "^7.9.2",
|
||||||
"@commitlint/config-conventional": "^8.3.4",
|
"@commitlint/config-conventional": "^8.3.4",
|
||||||
"@types/jest": "^25.1.4",
|
"@types/jest": "^25.2.1",
|
||||||
|
"babel-jest": "^25.2.6",
|
||||||
"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.4",
|
||||||
"detox": "^16.0.0",
|
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-config-satya164": "^3.1.5",
|
"eslint-config-satya164": "^3.1.6",
|
||||||
"husky": "^4.2.3",
|
"husky": "^4.2.3",
|
||||||
"jest": "^25.1.0",
|
"jest": "^25.2.7",
|
||||||
"lerna": "^3.20.2",
|
"lerna": "^3.20.2",
|
||||||
"prettier": "^2.0.1",
|
"prettier": "^2.0.4",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"react": "~16.9.0",
|
"react": "~16.9.0",
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
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.6](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.5...@react-navigation/bottom-tabs@5.2.6) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* mark type exports for all packages ([b71de6c](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/commit/b71de6cc799143f1d0e8a0cfcc34f0a2381f9840))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.5](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.4...@react-navigation/bottom-tabs@5.2.5) (2020-03-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.3...@react-navigation/bottom-tabs@5.2.4) (2020-03-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.2...@react-navigation/bottom-tabs@5.2.3) (2020-03-22)
|
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.2...@react-navigation/bottom-tabs@5.2.3) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||||
|
|||||||
@@ -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.2.3",
|
"version": "5.2.6",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@react-navigation/native": "^5.1.2",
|
"@react-navigation/native": "^5.1.5",
|
||||||
"@types/color": "^3.0.1",
|
"@types/color": "^3.0.1",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.61.22",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"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.3.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-navigation/native": "^5.0.5",
|
"@react-navigation/native": "^5.0.5",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export { default as BottomTabBar } from './views/BottomTabBar';
|
|||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
BottomTabNavigationOptions,
|
BottomTabNavigationOptions,
|
||||||
BottomTabNavigationProp,
|
BottomTabNavigationProp,
|
||||||
BottomTabBarProps,
|
BottomTabBarProps,
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export type BottomTabBarOptions = {
|
|||||||
*/
|
*/
|
||||||
inactiveTintColor?: string;
|
inactiveTintColor?: string;
|
||||||
/**
|
/**
|
||||||
* Background olor for the active tab.
|
* Background color for the active tab.
|
||||||
*/
|
*/
|
||||||
activeBackgroundColor?: string;
|
activeBackgroundColor?: string;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
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.8](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.7...@react-navigation/compat@5.1.8) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* use 1 as default in compatibility pop action ([4408117](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/commit/44081172d440c713ad3543a2d5e1e18ebc8f72a4))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.7](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.6...@react-navigation/compat@5.1.7) (2020-03-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/compat
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.5...@react-navigation/compat@5.1.6) (2020-03-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/compat
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.4...@react-navigation/compat@5.1.5) (2020-03-22)
|
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.4...@react-navigation/compat@5.1.5) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/compat
|
**Note:** Version bump only for package @react-navigation/compat
|
||||||
|
|||||||
@@ -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.5",
|
"version": "5.1.8",
|
||||||
"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": {
|
||||||
@@ -26,10 +26,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@react-navigation/native": "^5.1.2",
|
"@react-navigation/native": "^5.1.5",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"react": "~16.9.0",
|
"react": "~16.9.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-navigation/native": "^5.0.5",
|
"@react-navigation/native": "^5.0.5",
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export function push(routeName: string, params?: object, action?: never) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pop(n: number) {
|
export function pop(n: number = 1) {
|
||||||
return StackActions.pop(typeof n === 'number' ? { n } : n);
|
return StackActions.pop(typeof n === 'number' ? { n } : n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.3.2...@react-navigation/core@5.3.3) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* switch order of focus and blur events. closes [#7963](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/7963) ([ce3994c](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/ce3994c82c28669d5742017eb7627e9adf996933))
|
||||||
|
* workaround warning about setState in another component in render ([d4fd906](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/d4fd906915cc20d6fb21508384c05a540d8644d8))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.3.2](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.3.1...@react-navigation/core@5.3.2) (2020-03-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* handle no path property and undefined query params ([#7911](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/7911)) ([cd47915](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/cd47915861a56cd7eaa9ac79f5139cde56ca95a7))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.3.1](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.3.0...@react-navigation/core@5.3.1) (2020-03-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* don't emit events for screens that don't exist anymore ([1c00142](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/1c001424b595b40f9db9343096c833f75353b099))
|
||||||
|
* only call listeners for focused screen for global events ([3096de6](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/3096de62868a7ed9ed65e529c8ddfa001b9be486))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.3.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.2.3...@react-navigation/core@5.3.0) (2020-03-22)
|
# [5.3.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.2.3...@react-navigation/core@5.3.0) (2020-03-22)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.3.0",
|
"version": "5.3.3",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
"react-native",
|
"react-native",
|
||||||
@@ -29,24 +29,23 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.2.0",
|
"@react-navigation/routers": "^5.3.0",
|
||||||
"escape-string-regexp": "^2.0.0",
|
"escape-string-regexp": "^2.0.0",
|
||||||
"query-string": "^6.11.1",
|
"nanoid": "^3.0.2",
|
||||||
|
"query-string": "^6.12.0",
|
||||||
"react-is": "^16.13.0",
|
"react-is": "^16.13.0",
|
||||||
"shortid": "^2.2.15",
|
|
||||||
"use-subscription": "^1.4.0"
|
"use-subscription": "^1.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-is": "^16.7.1",
|
"@types/react-is": "^16.7.1",
|
||||||
"@types/shortid": "^0.0.29",
|
|
||||||
"@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.12.0",
|
||||||
"react-test-renderer": "~16.9.0",
|
"react-test-renderer": "~16.13.1",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*"
|
"react": "*"
|
||||||
|
|||||||
@@ -9,14 +9,15 @@ import {
|
|||||||
} from '@react-navigation/routers';
|
} from '@react-navigation/routers';
|
||||||
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
||||||
import NavigationBuilderContext from './NavigationBuilderContext';
|
import NavigationBuilderContext from './NavigationBuilderContext';
|
||||||
|
import { ScheduleUpdateContext } from './useScheduleUpdate';
|
||||||
import useFocusedListeners from './useFocusedListeners';
|
import useFocusedListeners from './useFocusedListeners';
|
||||||
import useDevTools from './useDevTools';
|
import useDevTools from './useDevTools';
|
||||||
import useStateGetters from './useStateGetters';
|
import useStateGetters from './useStateGetters';
|
||||||
|
import useEventEmitter from './useEventEmitter';
|
||||||
|
import useSyncState from './useSyncState';
|
||||||
import isSerializable from './isSerializable';
|
import isSerializable from './isSerializable';
|
||||||
|
|
||||||
import { NavigationContainerRef, NavigationContainerProps } from './types';
|
import { NavigationContainerRef, NavigationContainerProps } from './types';
|
||||||
import useEventEmitter from './useEventEmitter';
|
|
||||||
import useSyncState from './useSyncState';
|
|
||||||
|
|
||||||
type State = NavigationState | PartialState<NavigationState> | undefined;
|
type State = NavigationState | PartialState<NavigationState> | undefined;
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@ const BaseNavigationContainer = React.forwardRef(
|
|||||||
independent,
|
independent,
|
||||||
children,
|
children,
|
||||||
}: NavigationContainerProps,
|
}: NavigationContainerProps,
|
||||||
ref: React.Ref<NavigationContainerRef>
|
ref?: React.Ref<NavigationContainerRef>
|
||||||
) {
|
) {
|
||||||
const parent = React.useContext(NavigationStateContext);
|
const parent = React.useContext(NavigationStateContext);
|
||||||
|
|
||||||
@@ -112,7 +113,13 @@ const BaseNavigationContainer = React.forwardRef(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [state, getState, setState] = useSyncState<State>(() =>
|
const [
|
||||||
|
state,
|
||||||
|
getState,
|
||||||
|
setState,
|
||||||
|
scheduleUpdate,
|
||||||
|
flushUpdates,
|
||||||
|
] = useSyncState<State>(() =>
|
||||||
getPartialState(initialState == null ? undefined : initialState)
|
getPartialState(initialState == null ? undefined : initialState)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -218,6 +225,11 @@ const BaseNavigationContainer = React.forwardRef(
|
|||||||
[addFocusedListener, trackAction, addStateGetter]
|
[addFocusedListener, trackAction, addStateGetter]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const scheduleContext = React.useMemo(
|
||||||
|
() => ({ scheduleUpdate, flushUpdates }),
|
||||||
|
[scheduleUpdate, flushUpdates]
|
||||||
|
);
|
||||||
|
|
||||||
const context = React.useMemo(
|
const context = React.useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
state,
|
state,
|
||||||
@@ -263,11 +275,13 @@ const BaseNavigationContainer = React.forwardRef(
|
|||||||
}, [onStateChange, trackState, getRootState, emitter, state]);
|
}, [onStateChange, trackState, getRootState, emitter, state]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationBuilderContext.Provider value={builderContext}>
|
<ScheduleUpdateContext.Provider value={scheduleContext}>
|
||||||
<NavigationStateContext.Provider value={context}>
|
<NavigationBuilderContext.Provider value={builderContext}>
|
||||||
<EnsureSingleNavigator>{children}</EnsureSingleNavigator>
|
<NavigationStateContext.Provider value={context}>
|
||||||
</NavigationStateContext.Provider>
|
<EnsureSingleNavigator>{children}</EnsureSingleNavigator>
|
||||||
</NavigationBuilderContext.Provider>
|
</NavigationStateContext.Provider>
|
||||||
|
</NavigationBuilderContext.Provider>
|
||||||
|
</ScheduleUpdateContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -521,3 +521,209 @@ it('returns "/" for empty path', () => {
|
|||||||
|
|
||||||
expect(getPathFromState(state, config)).toBe('/');
|
expect(getPathFromState(state, config)).toBe('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('parses no path specified', () => {
|
||||||
|
const path = '/Foo/bar';
|
||||||
|
const config = {
|
||||||
|
Foo: {
|
||||||
|
screens: {
|
||||||
|
Foe: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Bar: 'bar',
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [{ name: 'Bar' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getPathFromState(state, config)).toBe(path);
|
||||||
|
expect(getPathFromState(getStateFromPath(path, config), config)).toBe(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses no path specified in nested config', () => {
|
||||||
|
const path = '/Foo/Foe/bar';
|
||||||
|
const config = {
|
||||||
|
Foo: {
|
||||||
|
path: 'foo',
|
||||||
|
screens: {
|
||||||
|
Foe: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Bar: 'bar',
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foe',
|
||||||
|
state: {
|
||||||
|
routes: [{ name: 'Bar' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getPathFromState(state, config)).toBe(path);
|
||||||
|
expect(getPathFromState(getStateFromPath(path, config), config)).toBe(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('strips undefined query params', () => {
|
||||||
|
const path = '/bar/sweet/apple/foo/bis/jane?count=10&valid=true';
|
||||||
|
const config = {
|
||||||
|
Foo: {
|
||||||
|
path: 'foo',
|
||||||
|
screens: {
|
||||||
|
Foe: {
|
||||||
|
path: 'foe',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Bar: 'bar/:type/:fruit',
|
||||||
|
Baz: {
|
||||||
|
path: 'baz',
|
||||||
|
screens: {
|
||||||
|
Bos: 'bos',
|
||||||
|
Bis: {
|
||||||
|
path: 'bis/:author',
|
||||||
|
stringify: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, (c) => c.toLowerCase()),
|
||||||
|
},
|
||||||
|
parse: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, (c) => c.toUpperCase()),
|
||||||
|
count: Number,
|
||||||
|
valid: Boolean,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bar',
|
||||||
|
params: { fruit: 'apple', type: 'sweet' },
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Baz',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bis',
|
||||||
|
params: {
|
||||||
|
author: 'Jane',
|
||||||
|
count: 10,
|
||||||
|
answer: undefined,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getPathFromState(state, config)).toBe(path);
|
||||||
|
expect(getPathFromState(getStateFromPath(path, config), config)).toBe(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles stripping all query params', () => {
|
||||||
|
const path = '/bar/sweet/apple/foo/bis/jane';
|
||||||
|
const config = {
|
||||||
|
Foo: {
|
||||||
|
path: 'foo',
|
||||||
|
screens: {
|
||||||
|
Foe: {
|
||||||
|
path: 'foe',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Bar: 'bar/:type/:fruit',
|
||||||
|
Baz: {
|
||||||
|
path: 'baz',
|
||||||
|
screens: {
|
||||||
|
Bos: 'bos',
|
||||||
|
Bis: {
|
||||||
|
path: 'bis/:author',
|
||||||
|
stringify: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, (c) => c.toLowerCase()),
|
||||||
|
},
|
||||||
|
parse: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, (c) => c.toUpperCase()),
|
||||||
|
count: Number,
|
||||||
|
valid: Boolean,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bar',
|
||||||
|
params: { fruit: 'apple', type: 'sweet' },
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Baz',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bis',
|
||||||
|
params: {
|
||||||
|
author: 'Jane',
|
||||||
|
count: undefined,
|
||||||
|
answer: undefined,
|
||||||
|
valid: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getPathFromState(state, config)).toBe(path);
|
||||||
|
expect(getPathFromState(getStateFromPath(path, config), config)).toBe(path);
|
||||||
|
});
|
||||||
|
|||||||
@@ -626,7 +626,7 @@ it('updates route params with setParams applied to parent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles change in route names', () => {
|
it('handles change in route names', async () => {
|
||||||
const TestNavigator = (props: any): any => {
|
const TestNavigator = (props: any): any => {
|
||||||
useNavigationBuilder(MockRouter, props);
|
useNavigationBuilder(MockRouter, props);
|
||||||
return null;
|
return null;
|
||||||
@@ -635,7 +635,7 @@ it('handles change in route names', () => {
|
|||||||
const onStateChange = jest.fn();
|
const onStateChange = jest.fn();
|
||||||
|
|
||||||
const root = render(
|
const root = render(
|
||||||
<BaseNavigationContainer onStateChange={onStateChange}>
|
<BaseNavigationContainer>
|
||||||
<TestNavigator initialRouteName="bar">
|
<TestNavigator initialRouteName="bar">
|
||||||
<Screen name="foo" component={jest.fn()} />
|
<Screen name="foo" component={jest.fn()} />
|
||||||
<Screen name="bar" component={jest.fn()} />
|
<Screen name="bar" component={jest.fn()} />
|
||||||
|
|||||||
@@ -262,8 +262,10 @@ it('sets initial options with setOptions', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const TestScreen = ({ navigation }: any): any => {
|
const TestScreen = ({ navigation }: any): any => {
|
||||||
navigation.setOptions({
|
React.useEffect(() => {
|
||||||
title: 'Hello world',
|
navigation.setOptions({
|
||||||
|
title: 'Hello world',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return 'Test screen';
|
return 'Test screen';
|
||||||
@@ -315,12 +317,12 @@ it('updates options with setOptions', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const TestScreen = ({ navigation }: any): any => {
|
const TestScreen = ({ navigation }: any): any => {
|
||||||
navigation.setOptions({
|
|
||||||
title: 'Hello world',
|
|
||||||
description: 'Something here',
|
|
||||||
});
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
navigation.setOptions({
|
||||||
|
title: 'Hello world',
|
||||||
|
description: 'Something here',
|
||||||
|
});
|
||||||
|
|
||||||
const timer = setTimeout(() =>
|
const timer = setTimeout(() =>
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
title: 'Hello again',
|
title: 'Hello again',
|
||||||
|
|||||||
@@ -97,6 +97,69 @@ it('fires focus and blur events in root navigator', () => {
|
|||||||
expect(fourthBlurCallback).toBeCalledTimes(0);
|
expect(fourthBlurCallback).toBeCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('fires focus event after blur', () => {
|
||||||
|
const TestNavigator = React.forwardRef((props: any, ref: any): any => {
|
||||||
|
const { state, navigation, descriptors } = useNavigationBuilder(
|
||||||
|
MockRouter,
|
||||||
|
props
|
||||||
|
);
|
||||||
|
|
||||||
|
React.useImperativeHandle(ref, () => navigation, [navigation]);
|
||||||
|
|
||||||
|
return state.routes.map((route) => descriptors[route.key].render());
|
||||||
|
});
|
||||||
|
|
||||||
|
const callback = jest.fn();
|
||||||
|
|
||||||
|
const Test = ({ route, navigation }: any) => {
|
||||||
|
React.useEffect(
|
||||||
|
() =>
|
||||||
|
navigation.addListener('focus', () => callback(route.name, 'focus')),
|
||||||
|
[navigation, route.name]
|
||||||
|
);
|
||||||
|
|
||||||
|
React.useEffect(
|
||||||
|
() => navigation.addListener('blur', () => callback(route.name, 'blur')),
|
||||||
|
[navigation, route.name]
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigation = React.createRef<any>();
|
||||||
|
|
||||||
|
const element = (
|
||||||
|
<BaseNavigationContainer>
|
||||||
|
<TestNavigator ref={navigation}>
|
||||||
|
<Screen name="first" component={Test} />
|
||||||
|
<Screen name="second" component={Test} />
|
||||||
|
</TestNavigator>
|
||||||
|
</BaseNavigationContainer>
|
||||||
|
);
|
||||||
|
|
||||||
|
render(element);
|
||||||
|
|
||||||
|
expect(callback.mock.calls).toEqual([['first', 'focus']]);
|
||||||
|
|
||||||
|
act(() => navigation.current.navigate('second'));
|
||||||
|
|
||||||
|
expect(callback.mock.calls).toEqual([
|
||||||
|
['first', 'focus'],
|
||||||
|
['first', 'blur'],
|
||||||
|
['second', 'focus'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
act(() => navigation.current.navigate('first'));
|
||||||
|
|
||||||
|
expect(callback.mock.calls).toEqual([
|
||||||
|
['first', 'focus'],
|
||||||
|
['first', 'blur'],
|
||||||
|
['second', 'focus'],
|
||||||
|
['second', 'blur'],
|
||||||
|
['first', 'focus'],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it('fires focus and blur events in nested navigator', () => {
|
it('fires focus and blur events in nested navigator', () => {
|
||||||
const TestNavigator = React.forwardRef((props: any, ref: any): any => {
|
const TestNavigator = React.forwardRef((props: any, ref: any): any => {
|
||||||
const { state, navigation, descriptors } = useNavigationBuilder(
|
const { state, navigation, descriptors } = useNavigationBuilder(
|
||||||
@@ -565,12 +628,10 @@ it('fires custom events added with listeners prop', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(firstCallback.mock.calls[0][0].target).toBe(undefined);
|
expect(firstCallback.mock.calls[0][0].target).toBe(undefined);
|
||||||
expect(secondCallback.mock.calls[0][0].target).toBe(undefined);
|
|
||||||
expect(thirdCallback.mock.calls[1][0].target).toBe(undefined);
|
|
||||||
|
|
||||||
expect(firstCallback).toBeCalledTimes(1);
|
expect(firstCallback).toBeCalledTimes(1);
|
||||||
expect(secondCallback).toBeCalledTimes(1);
|
expect(secondCallback).toBeCalledTimes(0);
|
||||||
expect(thirdCallback).toBeCalledTimes(2);
|
expect(thirdCallback).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("doesn't call same listener multiple times with listeners", () => {
|
it("doesn't call same listener multiple times with listeners", () => {
|
||||||
@@ -624,6 +685,91 @@ it("doesn't call same listener multiple times with listeners", () => {
|
|||||||
expect(callback).toBeCalledTimes(1);
|
expect(callback).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('fires listeners when callback is provided for listeners prop', () => {
|
||||||
|
const eventName = 'someSuperCoolEvent';
|
||||||
|
|
||||||
|
const TestNavigator = React.forwardRef((props: any, ref: any): any => {
|
||||||
|
const { state, navigation } = useNavigationBuilder(MockRouter, props);
|
||||||
|
|
||||||
|
React.useImperativeHandle(ref, () => ({ navigation, state }), [
|
||||||
|
navigation,
|
||||||
|
state,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstCallback = jest.fn();
|
||||||
|
const secondCallback = jest.fn();
|
||||||
|
const thirdCallback = jest.fn();
|
||||||
|
|
||||||
|
const ref = React.createRef<any>();
|
||||||
|
|
||||||
|
const element = (
|
||||||
|
<BaseNavigationContainer>
|
||||||
|
<TestNavigator ref={ref}>
|
||||||
|
<Screen
|
||||||
|
name="first"
|
||||||
|
listeners={({ route, navigation }) => ({
|
||||||
|
someSuperCoolEvent: (e) => firstCallback(e, route, navigation),
|
||||||
|
})}
|
||||||
|
component={jest.fn()}
|
||||||
|
/>
|
||||||
|
<Screen
|
||||||
|
name="second"
|
||||||
|
listeners={({ route, navigation }) => ({
|
||||||
|
someSuperCoolEvent: (e) => secondCallback(e, route, navigation),
|
||||||
|
})}
|
||||||
|
component={jest.fn()}
|
||||||
|
/>
|
||||||
|
<Screen
|
||||||
|
name="third"
|
||||||
|
listeners={({ route, navigation }) => ({
|
||||||
|
someSuperCoolEvent: (e) => thirdCallback(e, route, navigation),
|
||||||
|
})}
|
||||||
|
component={jest.fn()}
|
||||||
|
/>
|
||||||
|
</TestNavigator>
|
||||||
|
</BaseNavigationContainer>
|
||||||
|
);
|
||||||
|
|
||||||
|
render(element);
|
||||||
|
|
||||||
|
expect(firstCallback).toBeCalledTimes(0);
|
||||||
|
expect(secondCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdCallback).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
const target =
|
||||||
|
ref.current.state.routes[ref.current.state.routes.length - 1].key;
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
ref.current.navigation.emit({
|
||||||
|
type: eventName,
|
||||||
|
target,
|
||||||
|
data: 42,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstCallback).toBeCalledTimes(0);
|
||||||
|
expect(secondCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdCallback).toBeCalledTimes(1);
|
||||||
|
expect(thirdCallback.mock.calls[0][0].type).toBe('someSuperCoolEvent');
|
||||||
|
expect(thirdCallback.mock.calls[0][0].data).toBe(42);
|
||||||
|
expect(thirdCallback.mock.calls[0][0].target).toBe(target);
|
||||||
|
expect(thirdCallback.mock.calls[0][0].defaultPrevented).toBe(undefined);
|
||||||
|
expect(thirdCallback.mock.calls[0][0].preventDefault).toBe(undefined);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
ref.current.navigation.emit({ type: eventName });
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstCallback.mock.calls[0][0].target).toBe(undefined);
|
||||||
|
|
||||||
|
expect(firstCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdCallback).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('has option to prevent default', () => {
|
it('has option to prevent default', () => {
|
||||||
expect.assertions(5);
|
expect.assertions(5);
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ export default function getPathFromState(
|
|||||||
};
|
};
|
||||||
let currentOptions = options;
|
let currentOptions = options;
|
||||||
let pattern = route.name;
|
let pattern = route.name;
|
||||||
|
// we keep all the route names that appeared during going deeper in config in case the pattern is resolved to undefined
|
||||||
|
let nestedRouteNames = '';
|
||||||
|
|
||||||
while (route.name in currentOptions) {
|
while (route.name in currentOptions) {
|
||||||
if (typeof currentOptions[route.name] === 'string') {
|
if (typeof currentOptions[route.name] === 'string') {
|
||||||
@@ -77,11 +79,13 @@ export default function getPathFromState(
|
|||||||
}).screens
|
}).screens
|
||||||
) {
|
) {
|
||||||
pattern = (currentOptions[route.name] as { path: string }).path;
|
pattern = (currentOptions[route.name] as { path: string }).path;
|
||||||
|
nestedRouteNames = `${nestedRouteNames}/${route.name}`;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// if it is the end of state, we return pattern
|
// if it is the end of state, we return pattern
|
||||||
if (route.state === undefined) {
|
if (route.state === undefined) {
|
||||||
pattern = (currentOptions[route.name] as { path: string }).path;
|
pattern = (currentOptions[route.name] as { path: string }).path;
|
||||||
|
nestedRouteNames = `${nestedRouteNames}/${route.name}`;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
index =
|
index =
|
||||||
@@ -92,11 +96,13 @@ export default function getPathFromState(
|
|||||||
}).screens;
|
}).screens;
|
||||||
// if there is config for next route name, we go deeper
|
// if there is config for next route name, we go deeper
|
||||||
if (nextRoute.name in deeperConfig) {
|
if (nextRoute.name in deeperConfig) {
|
||||||
|
nestedRouteNames = `${nestedRouteNames}/${route.name}`;
|
||||||
route = nextRoute as Route<string> & { state?: State };
|
route = nextRoute as Route<string> & { state?: State };
|
||||||
currentOptions = deeperConfig;
|
currentOptions = deeperConfig;
|
||||||
} else {
|
} else {
|
||||||
// if not, there is no sense in going deeper in config
|
// if not, there is no sense in going deeper in config
|
||||||
pattern = (currentOptions[route.name] as { path: string }).path;
|
pattern = (currentOptions[route.name] as { path: string }).path;
|
||||||
|
nestedRouteNames = `${nestedRouteNames}/${route.name}`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,6 +110,11 @@ export default function getPathFromState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pattern === undefined) {
|
||||||
|
// cut the first `/`
|
||||||
|
pattern = nestedRouteNames.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
// we don't add empty path strings to path
|
// we don't add empty path strings to path
|
||||||
if (pattern !== '') {
|
if (pattern !== '') {
|
||||||
const config =
|
const config =
|
||||||
@@ -147,6 +158,12 @@ export default function getPathFromState(
|
|||||||
if (route.state) {
|
if (route.state) {
|
||||||
path += '/';
|
path += '/';
|
||||||
} else if (params) {
|
} else if (params) {
|
||||||
|
for (let param in params) {
|
||||||
|
if (params[param] === 'undefined') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||||
|
delete params[param];
|
||||||
|
}
|
||||||
|
}
|
||||||
const query = queryString.stringify(params);
|
const query = queryString.stringify(params);
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
|
|||||||
@@ -410,24 +410,19 @@ export type RouteConfig<
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export type NavigationContainerRef =
|
export type NavigationContainerRef = NavigationHelpers<ParamListBase> &
|
||||||
| (NavigationHelpers<ParamListBase> &
|
EventConsumer<{ state: { data: { state: NavigationState } } }> & {
|
||||||
EventConsumer<{ state: { data: { state: NavigationState } } }> & {
|
/**
|
||||||
/**
|
* Reset the navigation state of the root navigator to the provided state.
|
||||||
* Reset the navigation state of the root navigator to the provided state.
|
*
|
||||||
*
|
* @param state Navigation state object.
|
||||||
* @param state Navigation state object.
|
*/
|
||||||
*/
|
resetRoot(state?: PartialState<NavigationState> | NavigationState): void;
|
||||||
resetRoot(
|
/**
|
||||||
state?: PartialState<NavigationState> | NavigationState
|
* Get the rehydrated navigation state of the navigation tree.
|
||||||
): void;
|
*/
|
||||||
/**
|
getRootState(): NavigationState;
|
||||||
* Get the rehydrated navigation state of the navigation tree.
|
};
|
||||||
*/
|
|
||||||
getRootState(): NavigationState;
|
|
||||||
})
|
|
||||||
| undefined
|
|
||||||
| null;
|
|
||||||
|
|
||||||
export type TypedNavigator<
|
export type TypedNavigator<
|
||||||
ParamList extends ParamListBase,
|
ParamList extends ParamListBase,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export default function useFocusEvents({ state, emitter }: Options) {
|
|||||||
emitter.emit({ type: 'focus', target: currentFocusedKey });
|
emitter.emit({ type: 'focus', target: currentFocusedKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should only dispatch events when the focused key changed and navigator is focused
|
// We should only emit events when the focused key changed and navigator is focused
|
||||||
// When navigator is not focused, screens inside shouldn't receive focused status either
|
// When navigator is not focused, screens inside shouldn't receive focused status either
|
||||||
if (
|
if (
|
||||||
lastFocusedKey === currentFocusedKey ||
|
lastFocusedKey === currentFocusedKey ||
|
||||||
@@ -62,7 +62,7 @@ export default function useFocusEvents({ state, emitter }: Options) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emitter.emit({ type: 'focus', target: currentFocusedKey });
|
|
||||||
emitter.emit({ type: 'blur', target: lastFocusedKey });
|
emitter.emit({ type: 'blur', target: lastFocusedKey });
|
||||||
|
emitter.emit({ type: 'focus', target: currentFocusedKey });
|
||||||
}, [currentFocusedKey, emitter, navigation]);
|
}, [currentFocusedKey, emitter, navigation]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
} from './types';
|
} from './types';
|
||||||
import useStateGetters from './useStateGetters';
|
import useStateGetters from './useStateGetters';
|
||||||
import useOnGetState from './useOnGetState';
|
import useOnGetState from './useOnGetState';
|
||||||
|
import useScheduleUpdate from './useScheduleUpdate';
|
||||||
|
|
||||||
// This is to make TypeScript compiler happy
|
// This is to make TypeScript compiler happy
|
||||||
// eslint-disable-next-line babel/no-unused-expressions
|
// eslint-disable-next-line babel/no-unused-expressions
|
||||||
@@ -308,16 +309,13 @@ export default function useNavigationBuilder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
previousRouteRef.current &&
|
typeof route?.params?.screen === 'string' &&
|
||||||
route &&
|
route.params !== previousRouteRef.current?.params
|
||||||
route.params &&
|
|
||||||
typeof route.params.screen === 'string' &&
|
|
||||||
route.params !== previousRouteRef.current.params
|
|
||||||
) {
|
) {
|
||||||
// If the route was updated with new name and/or params, we should navigate there
|
// If the route was updated with new name and/or params, we should navigate there
|
||||||
// The update should be limited to current navigator only, so we call the router manually
|
// The update should be limited to current navigator only, so we call the router manually
|
||||||
const updatedState = router.getStateForAction(
|
const updatedState = router.getStateForAction(
|
||||||
state,
|
nextState,
|
||||||
CommonActions.navigate(route.params.screen, route.params.params),
|
CommonActions.navigate(route.params.screen, route.params.params),
|
||||||
{
|
{
|
||||||
routeNames,
|
routeNames,
|
||||||
@@ -331,17 +329,17 @@ export default function useNavigationBuilder<
|
|||||||
routeNames,
|
routeNames,
|
||||||
routeParamList,
|
routeParamList,
|
||||||
})
|
})
|
||||||
: state;
|
: nextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldUpdate = state !== nextState;
|
const shouldUpdate = state !== nextState;
|
||||||
|
|
||||||
React.useEffect(() => {
|
useScheduleUpdate(() => {
|
||||||
if (shouldUpdate) {
|
if (shouldUpdate) {
|
||||||
// If the state needs to be updated, we'll schedule an update with React
|
// If the state needs to be updated, we'll schedule an update
|
||||||
setState(nextState);
|
setState(nextState);
|
||||||
}
|
}
|
||||||
}, [nextState, setState, shouldUpdate]);
|
});
|
||||||
|
|
||||||
// The up-to-date state will come in next render, but we don't need to wait for it
|
// The up-to-date state will come in next render, but we don't need to wait for it
|
||||||
// We can't use the outdated state since the screens have changed, which will cause error due to mismatched config
|
// We can't use the outdated state since the screens have changed, which will cause error due to mismatched config
|
||||||
@@ -371,36 +369,40 @@ export default function useNavigationBuilder<
|
|||||||
const emitter = useEventEmitter((e) => {
|
const emitter = useEventEmitter((e) => {
|
||||||
let routeNames = [];
|
let routeNames = [];
|
||||||
|
|
||||||
let target: Route<string> | undefined;
|
let route: Route<string> | undefined;
|
||||||
|
|
||||||
if (e.target) {
|
if (e.target) {
|
||||||
target = state.routes.find((route) => route.key === e.target);
|
route = state.routes.find((route) => route.key === e.target);
|
||||||
|
|
||||||
if (target?.name) {
|
if (route?.name) {
|
||||||
routeNames.push(target.name);
|
routeNames.push(route.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
routeNames.push(...Object.keys(screens));
|
route = state.routes[state.index];
|
||||||
|
routeNames.push(
|
||||||
|
...Object.keys(screens).filter((name) => route?.name === name)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (route == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const navigation = descriptors[route.key].navigation;
|
||||||
|
|
||||||
const listeners = ([] as (((e: any) => void) | undefined)[])
|
const listeners = ([] as (((e: any) => void) | undefined)[])
|
||||||
.concat(
|
.concat(
|
||||||
...routeNames.map((name) => {
|
...routeNames.map((name) => {
|
||||||
const { listeners } = screens[name];
|
const { listeners } = screens[name];
|
||||||
|
const map =
|
||||||
|
typeof listeners === 'function'
|
||||||
|
? listeners({ route: route as any, navigation })
|
||||||
|
: listeners;
|
||||||
|
|
||||||
return listeners
|
return map
|
||||||
? Object.keys(listeners)
|
? Object.keys(map)
|
||||||
.filter((type) => type === e.type)
|
.filter((type) => type === e.type)
|
||||||
.map((type) => {
|
.map((type) => map?.[type])
|
||||||
if (typeof listeners === 'function') {
|
|
||||||
const route = target ?? state.routes[state.index];
|
|
||||||
const navigation = descriptors[route.key].navigation;
|
|
||||||
|
|
||||||
return listeners({ route: route as any, navigation })[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
return listeners[type];
|
|
||||||
})
|
|
||||||
: undefined;
|
: undefined;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import shortid from 'shortid';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
import { SingleNavigatorContext } from './EnsureSingleNavigator';
|
import { SingleNavigatorContext } from './EnsureSingleNavigator';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,7 +7,7 @@ import { SingleNavigatorContext } from './EnsureSingleNavigator';
|
|||||||
* This is used to prevent multiple navigators under a single container or screen.
|
* This is used to prevent multiple navigators under a single container or screen.
|
||||||
*/
|
*/
|
||||||
export default function useRegisterNavigator() {
|
export default function useRegisterNavigator() {
|
||||||
const [key] = React.useState(() => shortid());
|
const [key] = React.useState(() => nanoid());
|
||||||
const container = React.useContext(SingleNavigatorContext);
|
const container = React.useContext(SingleNavigatorContext);
|
||||||
|
|
||||||
if (container === undefined) {
|
if (container === undefined) {
|
||||||
|
|||||||
32
packages/core/src/useScheduleUpdate.tsx
Normal file
32
packages/core/src/useScheduleUpdate.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
const MISSING_CONTEXT_ERROR = "Couldn't find a schedule context.";
|
||||||
|
|
||||||
|
export const ScheduleUpdateContext = React.createContext<{
|
||||||
|
scheduleUpdate: (callback: () => void) => void;
|
||||||
|
flushUpdates: () => void;
|
||||||
|
}>({
|
||||||
|
scheduleUpdate() {
|
||||||
|
throw new Error(MISSING_CONTEXT_ERROR);
|
||||||
|
},
|
||||||
|
flushUpdates() {
|
||||||
|
throw new Error(MISSING_CONTEXT_ERROR);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When screen config changes, we want to update the navigator in the same update phase.
|
||||||
|
* However, navigation state is in the root component and React won't let us update it from a child.
|
||||||
|
* This is a workaround for that, the scheduled update is stored in the ref without actually calling setState.
|
||||||
|
* It lets all subsequent updates access the latest state so it stays correct.
|
||||||
|
* Then we call setState during after the component updates.
|
||||||
|
*/
|
||||||
|
export default function useScheduleUpdate(callback: () => void) {
|
||||||
|
const { scheduleUpdate, flushUpdates } = React.useContext(
|
||||||
|
ScheduleUpdateContext
|
||||||
|
);
|
||||||
|
|
||||||
|
scheduleUpdate(callback);
|
||||||
|
|
||||||
|
React.useEffect(flushUpdates);
|
||||||
|
}
|
||||||
@@ -2,8 +2,12 @@ import * as React from 'react';
|
|||||||
|
|
||||||
const UNINTIALIZED_STATE = {};
|
const UNINTIALIZED_STATE = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is definitely not compatible with concurrent mode, but we don't have a solution for sync state yet.
|
||||||
|
*/
|
||||||
export default function useSyncState<T>(initialState?: (() => T) | T) {
|
export default function useSyncState<T>(initialState?: (() => T) | T) {
|
||||||
const stateRef = React.useRef<T>(UNINTIALIZED_STATE as any);
|
const stateRef = React.useRef<T>(UNINTIALIZED_STATE as any);
|
||||||
|
const isSchedulingRef = React.useRef(false);
|
||||||
|
|
||||||
if (stateRef.current === UNINTIALIZED_STATE) {
|
if (stateRef.current === UNINTIALIZED_STATE) {
|
||||||
stateRef.current =
|
stateRef.current =
|
||||||
@@ -11,7 +15,7 @@ export default function useSyncState<T>(initialState?: (() => T) | T) {
|
|||||||
typeof initialState === 'function' ? initialState() : initialState;
|
typeof initialState === 'function' ? initialState() : initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [state, setTrackingState] = React.useState(stateRef.current);
|
const [trackingState, setTrackingState] = React.useState(stateRef.current);
|
||||||
|
|
||||||
const getState = React.useCallback(() => stateRef.current, []);
|
const getState = React.useCallback(() => stateRef.current, []);
|
||||||
|
|
||||||
@@ -21,8 +25,35 @@ export default function useSyncState<T>(initialState?: (() => T) | T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stateRef.current = state;
|
stateRef.current = state;
|
||||||
setTrackingState(state);
|
|
||||||
|
if (!isSchedulingRef.current) {
|
||||||
|
setTrackingState(state);
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return [state, getState, setState] as const;
|
const scheduleUpdate = React.useCallback((callback: () => void) => {
|
||||||
|
isSchedulingRef.current = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
callback();
|
||||||
|
} finally {
|
||||||
|
isSchedulingRef.current = false;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const flushUpdates = React.useCallback(() => {
|
||||||
|
// Make sure that the tracking state is up-to-date.
|
||||||
|
// We call it unconditionally, but React should skip the update if state is unchanged.
|
||||||
|
setTrackingState(stateRef.current);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// If we're rendering and the tracking state is out of date, update it immediately
|
||||||
|
// This will make sure that our updates are applied as early as possible.
|
||||||
|
if (trackingState !== stateRef.current) {
|
||||||
|
setTrackingState(stateRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = stateRef.current;
|
||||||
|
|
||||||
|
return [state, getState, setState, scheduleUpdate, flushUpdates] as const;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,42 @@
|
|||||||
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.1](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.4.0...@react-navigation/drawer@5.4.1) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* don't hide content from accessibility with permanent drawer ([cb2f157](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/cb2f157a561a2ce3f073eb4ccb567532c77bd869)), closes [#7976](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/issues/7976)
|
||||||
|
* mark type exports for all packages ([b71de6c](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/b71de6cc799143f1d0e8a0cfcc34f0a2381f9840))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [5.4.0](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.4...@react-navigation/drawer@5.4.0) (2020-03-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* disable only swipe gesture on safari ([105da6a](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/105da6ab2fe69847b676c4d4117638212cda1f9a))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add swipeEnabled option to disable swipe gesture in drawer ([#7834](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/issues/7834)) ([ac7f972](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/ac7f972e922a82cd32d943356941d100b68bd8b0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.3.4](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.3...@react-navigation/drawer@5.3.4) (2020-03-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.2...@react-navigation/drawer@5.3.3) (2020-03-22)
|
## [5.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.2...@react-navigation/drawer@5.3.3) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/drawer
|
**Note:** Version bump only for package @react-navigation/drawer
|
||||||
|
|||||||
@@ -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.3.3",
|
"version": "5.4.1",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@react-navigation/native": "^5.1.2",
|
"@react-navigation/native": "^5.1.5",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.61.22",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.0",
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"react-native-reanimated": "^1.7.0",
|
"react-native-reanimated": "^1.7.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.3.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-navigation/native": "^5.0.5",
|
"@react-navigation/native": "^5.0.5",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export { default as useIsDrawerOpen } from './utils/useIsDrawerOpen';
|
|||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
DrawerNavigationOptions,
|
DrawerNavigationOptions,
|
||||||
DrawerNavigationProp,
|
DrawerNavigationProp,
|
||||||
DrawerContentOptions,
|
DrawerContentOptions,
|
||||||
|
|||||||
@@ -111,9 +111,18 @@ export type DrawerNavigationOptions = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether you can use gestures to open or close the drawer.
|
* Whether you can use gestures to open or close the drawer.
|
||||||
|
* Setting this to `false` disables swipe gestures as well as tap on overlay to close.
|
||||||
|
* See `swipeEnabled` to disable only the swipe gesture.
|
||||||
* Defaults to `true`
|
* Defaults to `true`
|
||||||
*/
|
*/
|
||||||
gestureEnabled?: boolean;
|
gestureEnabled?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether you can use swipe gestures to open or close the drawer.
|
||||||
|
* Defaults to `true`
|
||||||
|
*/
|
||||||
|
swipeEnabled?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this screen should be unmounted when navigating away from it.
|
* Whether this screen should be unmounted when navigating away from it.
|
||||||
* Defaults to `false`.
|
* Defaults to `false`.
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ type Props = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onGestureRef?: (ref: PanGestureHandler | null) => void;
|
onGestureRef?: (ref: PanGestureHandler | null) => void;
|
||||||
gestureEnabled: boolean;
|
gestureEnabled: boolean;
|
||||||
|
swipeEnabled: boolean;
|
||||||
drawerPosition: 'left' | 'right';
|
drawerPosition: 'left' | 'right';
|
||||||
drawerType: 'front' | 'back' | 'slide' | 'permanent';
|
drawerType: 'front' | 'back' | 'slide' | 'permanent';
|
||||||
keyboardDismissMode: 'none' | 'on-drag';
|
keyboardDismissMode: 'none' | 'on-drag';
|
||||||
@@ -100,7 +101,7 @@ type Props = {
|
|||||||
* Disables the pan gesture by default on Apple devices in the browser.
|
* Disables the pan gesture by default on Apple devices in the browser.
|
||||||
* https://stackoverflow.com/a/9039885
|
* https://stackoverflow.com/a/9039885
|
||||||
*/
|
*/
|
||||||
function shouldEnableGesture(): boolean {
|
function shouldEnableSwipeGesture(): boolean {
|
||||||
if (
|
if (
|
||||||
Platform.OS === 'web' &&
|
Platform.OS === 'web' &&
|
||||||
typeof navigator !== 'undefined' &&
|
typeof navigator !== 'undefined' &&
|
||||||
@@ -115,11 +116,12 @@ function shouldEnableGesture(): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DrawerView extends React.PureComponent<Props> {
|
export default class DrawerView extends React.Component<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
drawerPostion: I18nManager.isRTL ? 'left' : 'right',
|
drawerPostion: I18nManager.isRTL ? 'left' : 'right',
|
||||||
drawerType: 'front',
|
drawerType: 'front',
|
||||||
gestureEnabled: shouldEnableGesture(),
|
gestureEnabled: true,
|
||||||
|
swipeEnabled: shouldEnableSwipeGesture(),
|
||||||
swipeEdgeWidth: 32,
|
swipeEdgeWidth: 32,
|
||||||
swipeVelocityThreshold: 500,
|
swipeVelocityThreshold: 500,
|
||||||
keyboardDismissMode: 'on-drag',
|
keyboardDismissMode: 'on-drag',
|
||||||
@@ -138,16 +140,11 @@ export default class DrawerView extends React.PureComponent<Props> {
|
|||||||
open,
|
open,
|
||||||
drawerPosition,
|
drawerPosition,
|
||||||
drawerType,
|
drawerType,
|
||||||
gestureEnabled,
|
|
||||||
swipeDistanceThreshold,
|
swipeDistanceThreshold,
|
||||||
swipeVelocityThreshold,
|
swipeVelocityThreshold,
|
||||||
hideStatusBar,
|
hideStatusBar,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (prevProps.gestureEnabled !== gestureEnabled) {
|
|
||||||
this.isGestureEnabled.setValue(gestureEnabled ? TRUE : FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// If we're not in the middle of a transition, sync the drawer's open state
|
// If we're not in the middle of a transition, sync the drawer's open state
|
||||||
typeof this.pendingOpenValue !== 'boolean' ||
|
typeof this.pendingOpenValue !== 'boolean' ||
|
||||||
@@ -223,9 +220,6 @@ export default class DrawerView extends React.PureComponent<Props> {
|
|||||||
private isDrawerTypeFront = new Value<Binary>(
|
private isDrawerTypeFront = new Value<Binary>(
|
||||||
this.props.drawerType === 'front' ? TRUE : FALSE
|
this.props.drawerType === 'front' ? TRUE : FALSE
|
||||||
);
|
);
|
||||||
private isGestureEnabled = new Value(
|
|
||||||
this.props.gestureEnabled ? TRUE : FALSE
|
|
||||||
);
|
|
||||||
|
|
||||||
private isOpen = new Value<Binary>(this.props.open ? TRUE : FALSE);
|
private isOpen = new Value<Binary>(this.props.open ? TRUE : FALSE);
|
||||||
private nextIsOpen = new Value<Binary | -1>(UNSET);
|
private nextIsOpen = new Value<Binary | -1>(UNSET);
|
||||||
@@ -554,6 +548,7 @@ export default class DrawerView extends React.PureComponent<Props> {
|
|||||||
const {
|
const {
|
||||||
open,
|
open,
|
||||||
gestureEnabled,
|
gestureEnabled,
|
||||||
|
swipeEnabled,
|
||||||
drawerPosition,
|
drawerPosition,
|
||||||
drawerType,
|
drawerType,
|
||||||
swipeEdgeWidth,
|
swipeEdgeWidth,
|
||||||
@@ -605,7 +600,7 @@ export default class DrawerView extends React.PureComponent<Props> {
|
|||||||
onGestureEvent={this.handleGestureEvent}
|
onGestureEvent={this.handleGestureEvent}
|
||||||
onHandlerStateChange={this.handleGestureStateChange}
|
onHandlerStateChange={this.handleGestureStateChange}
|
||||||
hitSlop={hitSlop}
|
hitSlop={hitSlop}
|
||||||
enabled={drawerType !== 'permanent' && gestureEnabled}
|
enabled={drawerType !== 'permanent' && gestureEnabled && swipeEnabled}
|
||||||
{...gestureHandlerProps}
|
{...gestureHandlerProps}
|
||||||
>
|
>
|
||||||
<Animated.View
|
<Animated.View
|
||||||
@@ -628,23 +623,27 @@ export default class DrawerView extends React.PureComponent<Props> {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
accessibilityElementsHidden={isOpen}
|
accessibilityElementsHidden={isOpen && drawerType !== 'permanent'}
|
||||||
importantForAccessibility={
|
importantForAccessibility={
|
||||||
isOpen ? 'no-hide-descendants' : 'auto'
|
isOpen && drawerType !== 'permanent'
|
||||||
|
? 'no-hide-descendants'
|
||||||
|
: 'auto'
|
||||||
}
|
}
|
||||||
style={styles.content}
|
style={styles.content}
|
||||||
>
|
>
|
||||||
{renderSceneContent({ progress })}
|
{renderSceneContent({ progress })}
|
||||||
</View>
|
</View>
|
||||||
{// Disable overlay if sidebar is permanent
|
{
|
||||||
drawerType === 'permanent' ? null : (
|
// Disable overlay if sidebar is permanent
|
||||||
<TapGestureHandler
|
drawerType === 'permanent' ? null : (
|
||||||
enabled={gestureEnabled}
|
<TapGestureHandler
|
||||||
onHandlerStateChange={this.handleTapStateChange}
|
enabled={gestureEnabled}
|
||||||
>
|
onHandlerStateChange={this.handleTapStateChange}
|
||||||
<Overlay progress={progress} style={overlayStyle} />
|
>
|
||||||
</TapGestureHandler>
|
<Overlay progress={progress} style={overlayStyle} />
|
||||||
)}
|
</TapGestureHandler>
|
||||||
|
)
|
||||||
|
}
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
{drawerType === 'permanent' ? null : (
|
{drawerType === 'permanent' ? null : (
|
||||||
<Animated.Code
|
<Animated.Code
|
||||||
@@ -659,7 +658,7 @@ export default class DrawerView extends React.PureComponent<Props> {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Animated.View
|
<Animated.View
|
||||||
accessibilityViewIsModal={isOpen}
|
accessibilityViewIsModal={isOpen && drawerType !== 'permanent'}
|
||||||
removeClippedSubviews={Platform.OS !== 'ios'}
|
removeClippedSubviews={Platform.OS !== 'ios'}
|
||||||
onLayout={this.handleDrawerLayout}
|
onLayout={this.handleDrawerLayout}
|
||||||
style={[
|
style={[
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ export default function DrawerView({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const activeKey = state.routes[state.index].key;
|
const activeKey = state.routes[state.index].key;
|
||||||
const { gestureEnabled } = descriptors[activeKey].options;
|
const { gestureEnabled, swipeEnabled } = descriptors[activeKey].options;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GestureHandlerWrapper style={styles.content}>
|
<GestureHandlerWrapper style={styles.content}>
|
||||||
@@ -210,6 +210,7 @@ export default function DrawerView({
|
|||||||
<Drawer
|
<Drawer
|
||||||
open={isDrawerOpen}
|
open={isDrawerOpen}
|
||||||
gestureEnabled={gestureEnabled}
|
gestureEnabled={gestureEnabled}
|
||||||
|
swipeEnabled={swipeEnabled}
|
||||||
onOpen={handleDrawerOpen}
|
onOpen={handleDrawerOpen}
|
||||||
onClose={handleDrawerClose}
|
onClose={handleDrawerClose}
|
||||||
onGestureRef={(ref) => {
|
onGestureRef={(ref) => {
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
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.8](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.7...@react-navigation/material-bottom-tabs@5.1.8) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* mark type exports for all packages ([b71de6c](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/commit/b71de6cc799143f1d0e8a0cfcc34f0a2381f9840))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.7](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.6...@react-navigation/material-bottom-tabs@5.1.7) (2020-03-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.5...@react-navigation/material-bottom-tabs@5.1.6) (2020-03-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.4...@react-navigation/material-bottom-tabs@5.1.5) (2020-03-22)
|
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.4...@react-navigation/material-bottom-tabs@5.1.5) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
||||||
|
|||||||
@@ -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.5",
|
"version": "5.1.8",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -36,16 +36,16 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@react-navigation/native": "^5.1.2",
|
"@react-navigation/native": "^5.1.5",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.61.22",
|
||||||
"@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.6.0",
|
"react-native-paper": "^3.7.0",
|
||||||
"react-native-vector-icons": "^6.6.0",
|
"react-native-vector-icons": "^6.6.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-navigation/native": "^5.0.5",
|
"@react-navigation/native": "^5.0.5",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export { default as MaterialBottomTabView } from './views/MaterialBottomTabView'
|
|||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
MaterialBottomTabNavigationOptions,
|
MaterialBottomTabNavigationOptions,
|
||||||
MaterialBottomTabNavigationProp,
|
MaterialBottomTabNavigationProp,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
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.8](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.7...@react-navigation/material-top-tabs@5.1.8) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* mark type exports for all packages ([b71de6c](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/commit/b71de6cc799143f1d0e8a0cfcc34f0a2381f9840))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.7](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.6...@react-navigation/material-top-tabs@5.1.7) (2020-03-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.5...@react-navigation/material-top-tabs@5.1.6) (2020-03-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.4...@react-navigation/material-top-tabs@5.1.5) (2020-03-22)
|
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.4...@react-navigation/material-top-tabs@5.1.5) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
||||||
|
|||||||
@@ -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.5",
|
"version": "5.1.8",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@react-navigation/native": "^5.1.2",
|
"@react-navigation/native": "^5.1.5",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.61.22",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.0",
|
||||||
@@ -47,8 +47,8 @@
|
|||||||
"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.7.0",
|
||||||
"react-native-tab-view": "^2.13.0",
|
"react-native-tab-view": "^2.14.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-navigation/native": "^5.0.5",
|
"@react-navigation/native": "^5.0.5",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export { default as MaterialTopTabBar } from './views/MaterialTopTabBar';
|
|||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
MaterialTopTabNavigationOptions,
|
MaterialTopTabNavigationOptions,
|
||||||
MaterialTopTabNavigationProp,
|
MaterialTopTabNavigationProp,
|
||||||
MaterialTopTabBarProps,
|
MaterialTopTabBarProps,
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
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.5](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.4...@react-navigation/native@5.1.5) (2020-04-08)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.4](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.3...@react-navigation/native@5.1.4) (2020-03-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.1.3](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.2...@react-navigation/native@5.1.3) (2020-03-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add info about android launchMode in useLinking error ([d94e43c](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/d94e43c3c8625b209a5c883b8cb560496d07fda7))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.1.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.1...@react-navigation/native@5.1.2) (2020-03-22)
|
## [5.1.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.1...@react-navigation/native@5.1.2) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/native
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|||||||
@@ -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.1.2",
|
"version": "5.1.5",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native",
|
"react-native",
|
||||||
"react-navigation",
|
"react-navigation",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^5.3.0"
|
"@react-navigation/core": "^5.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"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.12.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type Props = NavigationContainerProps & {
|
|||||||
*/
|
*/
|
||||||
const NavigationContainer = React.forwardRef(function NavigationContainer(
|
const NavigationContainer = React.forwardRef(function NavigationContainer(
|
||||||
{ theme = DefaultTheme, ...rest }: Props,
|
{ theme = DefaultTheme, ...rest }: Props,
|
||||||
ref: React.Ref<NavigationContainerRef>
|
ref?: React.Ref<NavigationContainerRef | null>
|
||||||
) {
|
) {
|
||||||
const refContainer = React.useRef<NavigationContainerRef>(null);
|
const refContainer = React.useRef<NavigationContainerRef>(null);
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export type LinkingOptions = {
|
|||||||
*/
|
*/
|
||||||
getStateFromPath?: typeof getStateFromPathDefault;
|
getStateFromPath?: typeof getStateFromPathDefault;
|
||||||
/**
|
/**
|
||||||
* Custom function to conver the state object to a valid URL (advanced).
|
* Custom function to convert the state object to a valid URL (advanced).
|
||||||
*/
|
*/
|
||||||
getPathFromState?: typeof getPathFromStateDefault;
|
getPathFromState?: typeof getPathFromStateDefault;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Linking } from 'react-native';
|
import { Linking, Platform } from 'react-native';
|
||||||
import {
|
import {
|
||||||
getActionFromState,
|
getActionFromState,
|
||||||
getStateFromPath as getStateFromPathDefault,
|
getStateFromPath as getStateFromPathDefault,
|
||||||
@@ -20,7 +20,10 @@ export default function useLinking(
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isUsingLinking) {
|
if (isUsingLinking) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Looks like you are using 'useLinking' in multiple components. This is likely an error since deep links should only be handled in one place to avoid conflicts."
|
"Looks like you are using 'useLinking' in multiple components. This is likely an error since deep links should only be handled in one place to avoid conflicts." +
|
||||||
|
(Platform.OS === 'android'
|
||||||
|
? "\n\nIf you're not using it in multiple components, ensure that you have set 'android:launchMode=singleTask' in the '<activity />' section of the 'AndroidManifest.xml' file to avoid launching multiple activities which run multiple instances of the root component."
|
||||||
|
: '')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
isUsingLinking = true;
|
isUsingLinking = true;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default function useLinking(
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isUsingLinking) {
|
if (isUsingLinking) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Looks like you are using 'useLinking' in multiple components. This is likely an error since URL integration should only be handled in one place to avoid conflicts."
|
"Looks like you are using 'useLinking' in multiple components. This is likely an error since URL integration should only be handled in one place to avoid conflicts. Also ensure that you set your android activity launchMode to single task in your AndroiManifest.xml file."
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
isUsingLinking = true;
|
isUsingLinking = true;
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
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/routers/compare/@react-navigation/routers@5.2.1...@react-navigation/routers@5.3.0) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* separate normal exports and type exports ([303f0b7](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/commit/303f0b78a5ab717b2d606cd9c8a22f3dae051f0f))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* make replace bubble up ([ba1f405](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/commit/ba1f4051299ad86001592b8d3601c16fece159df))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.1](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.2.0...@react-navigation/routers@5.2.1) (2020-03-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/routers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.2.0](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.1.1...@react-navigation/routers@5.2.0) (2020-03-22)
|
# [5.2.0](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.1.1...@react-navigation/routers@5.2.0) (2020-03-22)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.2.0",
|
"version": "5.3.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
"react-native",
|
"react-native",
|
||||||
@@ -30,12 +30,12 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"shortid": "^2.2.15"
|
"nanoid": "^3.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"@react-native-community/bob": {
|
"@react-native-community/bob": {
|
||||||
"source": "src",
|
"source": "src",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import shortid from 'shortid';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
import { CommonNavigationAction, NavigationState, PartialState } from './types';
|
import { CommonNavigationAction, NavigationState, PartialState } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,9 +55,7 @@ const BaseRouter = {
|
|||||||
return {
|
return {
|
||||||
...nextState,
|
...nextState,
|
||||||
routes: nextState.routes.map((route) =>
|
routes: nextState.routes.map((route) =>
|
||||||
route.key
|
route.key ? route : { ...route, key: `${route.name}-${nanoid()}` }
|
||||||
? route
|
|
||||||
: { ...route, key: `${route.name}-${shortid()}` }
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import shortid from 'shortid';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
import {
|
import {
|
||||||
PartialState,
|
PartialState,
|
||||||
CommonNavigationAction,
|
CommonNavigationAction,
|
||||||
@@ -115,7 +115,7 @@ export default function DrawerRouter(
|
|||||||
...state,
|
...state,
|
||||||
stale: false,
|
stale: false,
|
||||||
type: 'drawer',
|
type: 'drawer',
|
||||||
key: `drawer-${shortid()}`,
|
key: `drawer-${nanoid()}`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ export default function DrawerRouter(
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
type: 'drawer',
|
type: 'drawer',
|
||||||
key: `drawer-${shortid()}`,
|
key: `drawer-${nanoid()}`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import shortid from 'shortid';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
import BaseRouter from './BaseRouter';
|
import BaseRouter from './BaseRouter';
|
||||||
import {
|
import {
|
||||||
NavigationState,
|
NavigationState,
|
||||||
@@ -113,12 +113,12 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
return {
|
return {
|
||||||
stale: false,
|
stale: false,
|
||||||
type: 'stack',
|
type: 'stack',
|
||||||
key: `stack-${shortid()}`,
|
key: `stack-${nanoid()}`,
|
||||||
index: 0,
|
index: 0,
|
||||||
routeNames,
|
routeNames,
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
key: `${initialRouteName}-${shortid()}`,
|
key: `${initialRouteName}-${nanoid()}`,
|
||||||
name: initialRouteName,
|
name: initialRouteName,
|
||||||
params: routeParamList[initialRouteName],
|
params: routeParamList[initialRouteName],
|
||||||
},
|
},
|
||||||
@@ -139,7 +139,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
(route) =>
|
(route) =>
|
||||||
({
|
({
|
||||||
...route,
|
...route,
|
||||||
key: route.key || `${route.name}-${shortid()}`,
|
key: route.key || `${route.name}-${nanoid()}`,
|
||||||
params:
|
params:
|
||||||
routeParamList[route.name] !== undefined
|
routeParamList[route.name] !== undefined
|
||||||
? {
|
? {
|
||||||
@@ -157,7 +157,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
: routeNames[0];
|
: routeNames[0];
|
||||||
|
|
||||||
routes.push({
|
routes.push({
|
||||||
key: `${initialRouteName}-${shortid()}`,
|
key: `${initialRouteName}-${nanoid()}`,
|
||||||
name: initialRouteName,
|
name: initialRouteName,
|
||||||
params: routeParamList[initialRouteName],
|
params: routeParamList[initialRouteName],
|
||||||
});
|
});
|
||||||
@@ -166,7 +166,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
return {
|
return {
|
||||||
stale: false,
|
stale: false,
|
||||||
type: 'stack',
|
type: 'stack',
|
||||||
key: `stack-${shortid()}`,
|
key: `stack-${nanoid()}`,
|
||||||
index: routes.length - 1,
|
index: routes.length - 1,
|
||||||
routeNames,
|
routeNames,
|
||||||
routes,
|
routes,
|
||||||
@@ -186,7 +186,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
: routeNames[0];
|
: routeNames[0];
|
||||||
|
|
||||||
routes.push({
|
routes.push({
|
||||||
key: `${initialRouteName}-${shortid()}`,
|
key: `${initialRouteName}-${nanoid()}`,
|
||||||
name: initialRouteName,
|
name: initialRouteName,
|
||||||
params: routeParamList[initialRouteName],
|
params: routeParamList[initialRouteName],
|
||||||
});
|
});
|
||||||
@@ -219,9 +219,10 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'REPLACE': {
|
case 'REPLACE': {
|
||||||
const index = action.source
|
const index =
|
||||||
? state.routes.findIndex((r) => r.key === action.source)
|
action.target === state.key && action.source
|
||||||
: state.index;
|
? state.routes.findIndex((r) => r.key === action.source)
|
||||||
|
: state.index;
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
return null;
|
return null;
|
||||||
@@ -238,7 +239,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
routes: state.routes.map((route, i) =>
|
routes: state.routes.map((route, i) =>
|
||||||
i === index
|
i === index
|
||||||
? {
|
? {
|
||||||
key: key !== undefined ? key : `${name}-${shortid()}`,
|
key: key !== undefined ? key : `${name}-${nanoid()}`,
|
||||||
name,
|
name,
|
||||||
params:
|
params:
|
||||||
routeParamList[name] !== undefined
|
routeParamList[name] !== undefined
|
||||||
@@ -263,7 +264,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|||||||
{
|
{
|
||||||
key:
|
key:
|
||||||
action.payload.key === undefined
|
action.payload.key === undefined
|
||||||
? `${action.payload.name}-${shortid()}`
|
? `${action.payload.name}-${nanoid()}`
|
||||||
: action.payload.key,
|
: action.payload.key,
|
||||||
name: action.payload.name,
|
name: action.payload.name,
|
||||||
params:
|
params:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import shortid from 'shortid';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
import BaseRouter from './BaseRouter';
|
import BaseRouter from './BaseRouter';
|
||||||
import {
|
import {
|
||||||
NavigationState,
|
NavigationState,
|
||||||
@@ -126,7 +126,7 @@ export default function TabRouter({
|
|||||||
|
|
||||||
const routes = routeNames.map((name) => ({
|
const routes = routeNames.map((name) => ({
|
||||||
name,
|
name,
|
||||||
key: `${name}-${shortid()}`,
|
key: `${name}-${nanoid()}`,
|
||||||
params: routeParamList[name],
|
params: routeParamList[name],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ export default function TabRouter({
|
|||||||
return {
|
return {
|
||||||
stale: false,
|
stale: false,
|
||||||
type: 'tab',
|
type: 'tab',
|
||||||
key: `tab-${shortid()}`,
|
key: `tab-${nanoid()}`,
|
||||||
index,
|
index,
|
||||||
routeNames,
|
routeNames,
|
||||||
history,
|
history,
|
||||||
@@ -161,7 +161,7 @@ export default function TabRouter({
|
|||||||
key:
|
key:
|
||||||
route && route.name === name && route.key
|
route && route.name === name && route.key
|
||||||
? route.key
|
? route.key
|
||||||
: `${name}-${shortid()}`,
|
: `${name}-${nanoid()}`,
|
||||||
params:
|
params:
|
||||||
routeParamList[name] !== undefined
|
routeParamList[name] !== undefined
|
||||||
? {
|
? {
|
||||||
@@ -195,7 +195,7 @@ export default function TabRouter({
|
|||||||
return {
|
return {
|
||||||
stale: false,
|
stale: false,
|
||||||
type: 'tab',
|
type: 'tab',
|
||||||
key: `tab-${shortid()}`,
|
key: `tab-${nanoid()}`,
|
||||||
index,
|
index,
|
||||||
routeNames,
|
routeNames,
|
||||||
history,
|
history,
|
||||||
@@ -208,7 +208,7 @@ export default function TabRouter({
|
|||||||
(name) =>
|
(name) =>
|
||||||
state.routes.find((r) => r.name === name) || {
|
state.routes.find((r) => r.name === name) || {
|
||||||
name,
|
name,
|
||||||
key: `${name}-${shortid()}`,
|
key: `${name}-${nanoid()}`,
|
||||||
params: routeParamList[name],
|
params: routeParamList[name],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import BaseRouter from '../BaseRouter';
|
import BaseRouter from '../BaseRouter';
|
||||||
import * as CommonActions from '../CommonActions';
|
import * as CommonActions from '../CommonActions';
|
||||||
|
|
||||||
jest.mock('shortid', () => () => 'test');
|
jest.mock('nanoid/non-secure', () => ({ nanoid: () => 'test' }));
|
||||||
|
|
||||||
const STATE = {
|
const STATE = {
|
||||||
stale: false as const,
|
stale: false as const,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
DrawerNavigationState,
|
DrawerNavigationState,
|
||||||
} from '..';
|
} from '..';
|
||||||
|
|
||||||
jest.mock('shortid', () => () => 'test');
|
jest.mock('nanoid/non-secure', () => ({ nanoid: () => 'test' }));
|
||||||
|
|
||||||
it('gets initial state from route names and params with initialRouteName', () => {
|
it('gets initial state from route names and params with initialRouteName', () => {
|
||||||
const router = DrawerRouter({ initialRouteName: 'baz' });
|
const router = DrawerRouter({ initialRouteName: 'baz' });
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { CommonActions, StackRouter, StackActions } from '..';
|
import { CommonActions, StackRouter, StackActions } from '..';
|
||||||
|
|
||||||
jest.mock('shortid', () => () => 'test');
|
jest.mock('nanoid/non-secure', () => ({ nanoid: () => 'test' }));
|
||||||
|
|
||||||
it('gets initial state from route names and params with initialRouteName', () => {
|
it('gets initial state from route names and params with initialRouteName', () => {
|
||||||
const router = StackRouter({ initialRouteName: 'baz' });
|
const router = StackRouter({ initialRouteName: 'baz' });
|
||||||
@@ -720,7 +720,7 @@ it('replaces focused screen with replace', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('replaces source screen with replace', () => {
|
it('replaces active screen with replace', () => {
|
||||||
const router = StackRouter({});
|
const router = StackRouter({});
|
||||||
const options = {
|
const options = {
|
||||||
routeNames: ['foo', 'bar', 'baz', 'qux'],
|
routeNames: ['foo', 'bar', 'baz', 'qux'],
|
||||||
@@ -754,8 +754,8 @@ it('replaces source screen with replace', () => {
|
|||||||
index: 1,
|
index: 1,
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'foo', name: 'foo' },
|
{ key: 'foo', name: 'foo' },
|
||||||
{ key: 'bar', name: 'bar', params: { fruit: 'orange' } },
|
|
||||||
{ key: 'qux-test', name: 'qux', params: { answer: 42 } },
|
{ key: 'qux-test', name: 'qux', params: { answer: 42 } },
|
||||||
|
{ key: 'baz', name: 'baz' },
|
||||||
],
|
],
|
||||||
routeNames: ['foo', 'bar', 'baz', 'qux'],
|
routeNames: ['foo', 'bar', 'baz', 'qux'],
|
||||||
});
|
});
|
||||||
@@ -785,6 +785,7 @@ it("doesn't handle replace if source key isn't present", () => {
|
|||||||
{
|
{
|
||||||
...StackActions.replace('qux', { answer: 42 }),
|
...StackActions.replace('qux', { answer: 42 }),
|
||||||
source: 'magic',
|
source: 'magic',
|
||||||
|
target: 'root',
|
||||||
},
|
},
|
||||||
options
|
options
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { CommonActions, TabRouter, TabActions, TabNavigationState } from '..';
|
import { CommonActions, TabRouter, TabActions, TabNavigationState } from '..';
|
||||||
|
|
||||||
jest.mock('shortid', () => () => 'test');
|
jest.mock('nanoid/non-secure', () => ({ nanoid: () => 'test' }));
|
||||||
|
|
||||||
it('gets initial state from route names and params with initialRouteName', () => {
|
it('gets initial state from route names and params with initialRouteName', () => {
|
||||||
const router = TabRouter({ initialRouteName: 'baz' });
|
const router = TabRouter({ initialRouteName: 'baz' });
|
||||||
|
|||||||
@@ -4,27 +4,27 @@ export { CommonActions };
|
|||||||
|
|
||||||
export { default as BaseRouter } from './BaseRouter';
|
export { default as BaseRouter } from './BaseRouter';
|
||||||
|
|
||||||
export {
|
export { default as StackRouter, StackActions } from './StackRouter';
|
||||||
default as StackRouter,
|
|
||||||
StackActions,
|
export type {
|
||||||
StackActionHelpers,
|
StackActionHelpers,
|
||||||
StackActionType,
|
StackActionType,
|
||||||
StackRouterOptions,
|
StackRouterOptions,
|
||||||
StackNavigationState,
|
StackNavigationState,
|
||||||
} from './StackRouter';
|
} from './StackRouter';
|
||||||
|
|
||||||
export {
|
export { default as TabRouter, TabActions } from './TabRouter';
|
||||||
default as TabRouter,
|
|
||||||
TabActions,
|
export type {
|
||||||
TabActionHelpers,
|
TabActionHelpers,
|
||||||
TabActionType,
|
TabActionType,
|
||||||
TabRouterOptions,
|
TabRouterOptions,
|
||||||
TabNavigationState,
|
TabNavigationState,
|
||||||
} from './TabRouter';
|
} from './TabRouter';
|
||||||
|
|
||||||
export {
|
export { default as DrawerRouter, DrawerActions } from './DrawerRouter';
|
||||||
default as DrawerRouter,
|
|
||||||
DrawerActions,
|
export type {
|
||||||
DrawerActionHelpers,
|
DrawerActionHelpers,
|
||||||
DrawerActionType,
|
DrawerActionType,
|
||||||
DrawerRouterOptions,
|
DrawerRouterOptions,
|
||||||
|
|||||||
@@ -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.2.10](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.9...@react-navigation/stack@5.2.10) (2020-04-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* make color of shadow element same as card color in stack ([f1a8bce](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/f1a8bceba5b736e9f59862a8ae819342209a46f2))
|
||||||
|
* mark type exports for all packages ([b71de6c](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/b71de6cc799143f1d0e8a0cfcc34f0a2381f9840))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.9](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.8...@react-navigation/stack@5.2.9) (2020-03-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* dismiss keyboard on screen change for android ([8432e5a](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/8432e5ab25f041af8538ea7fb35e97cfcf1f983e))
|
||||||
|
* finish stack animation on CANCELLED event ([#7898](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7898)) ([d649fbc](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/d649fbc6691871f0348076bce185d11a183c02cf)), closes [#7897](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7897)
|
||||||
|
* when comparing changed routes, only check keys ([9a8fea8](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/9a8fea8f2c1bdabfc5dd87e5c3ff4e7b97aef47d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.7](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.6...@react-navigation/stack@5.2.7) (2020-03-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add pointerEvents=box-none to overlay View ([#7871](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7871)) ([e097df8](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/e097df880adab984aae29f847003d2548cfbdce5))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.6](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.5...@react-navigation/stack@5.2.6) (2020-03-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [5.2.5](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.4...@react-navigation/stack@5.2.5) (2020-03-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix swipe gestures requiring a lot of velocity to dismiss ([61f16d3](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/61f16d3f25cbbcc00d699dd09c5f4abde9b17d5a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.3...@react-navigation/stack@5.2.4) (2020-03-22)
|
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.3...@react-navigation/stack@5.2.4) (2020-03-22)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.4",
|
"version": "5.2.10",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.10.0",
|
||||||
"@react-native-community/masked-view": "^0.1.7",
|
"@react-native-community/masked-view": "^0.1.7",
|
||||||
"@react-navigation/native": "^5.1.2",
|
"@react-navigation/native": "^5.1.5",
|
||||||
"@types/color": "^3.0.1",
|
"@types/color": "^3.0.1",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.23",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.61.22",
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"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.3.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-native-community/masked-view": ">= 0.1.0",
|
"@react-native-community/masked-view": ">= 0.1.0",
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export { default as useGestureHandlerRef } from './utils/useGestureHandlerRef';
|
|||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
StackNavigationOptions,
|
StackNavigationOptions,
|
||||||
StackNavigationProp,
|
StackNavigationProp,
|
||||||
StackHeaderProps,
|
StackHeaderProps,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { TextInput } from 'react-native';
|
import { TextInput, Platform, Keyboard } from 'react-native';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@@ -56,7 +56,9 @@ export default class KeyboardManager extends React.Component<Props> {
|
|||||||
|
|
||||||
const input = this.previouslyFocusedTextInput;
|
const input = this.previouslyFocusedTextInput;
|
||||||
|
|
||||||
if (input) {
|
if (Platform.OS === 'android') {
|
||||||
|
Keyboard.dismiss();
|
||||||
|
} else if (input) {
|
||||||
TextInput.State.blurTextInput(input);
|
TextInput.State.blurTextInput(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,11 +246,21 @@ export default class Card extends React.Component<Props> {
|
|||||||
this.handleStartInteraction();
|
this.handleStartInteraction();
|
||||||
onGestureBegin?.();
|
onGestureBegin?.();
|
||||||
break;
|
break;
|
||||||
case GestureState.CANCELLED:
|
case GestureState.CANCELLED: {
|
||||||
this.isSwiping.setValue(FALSE);
|
this.isSwiping.setValue(FALSE);
|
||||||
this.handleEndInteraction();
|
this.handleEndInteraction();
|
||||||
|
|
||||||
|
const velocity =
|
||||||
|
gestureDirection === 'vertical' ||
|
||||||
|
gestureDirection === 'vertical-inverted'
|
||||||
|
? nativeEvent.velocityY
|
||||||
|
: nativeEvent.velocityX;
|
||||||
|
|
||||||
|
this.animate({ closing: this.props.closing, velocity });
|
||||||
|
|
||||||
onGestureCanceled?.();
|
onGestureCanceled?.();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GestureState.END: {
|
case GestureState.END: {
|
||||||
this.isSwiping.setValue(FALSE);
|
this.isSwiping.setValue(FALSE);
|
||||||
|
|
||||||
@@ -272,8 +282,7 @@ export default class Card extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const closing =
|
const closing =
|
||||||
(translation + velocity) *
|
(translation + velocity * gestureVelocityImpact) *
|
||||||
gestureVelocityImpact *
|
|
||||||
getInvertedMultiplier(gestureDirection) >
|
getInvertedMultiplier(gestureDirection) >
|
||||||
distance / 2
|
distance / 2
|
||||||
? velocity !== 0 || translation !== 0
|
? velocity !== 0 || translation !== 0
|
||||||
@@ -481,7 +490,7 @@ export default class Card extends React.Component<Props> {
|
|||||||
<CardAnimationContext.Provider value={animationContext}>
|
<CardAnimationContext.Provider value={animationContext}>
|
||||||
<View pointerEvents="box-none" {...rest}>
|
<View pointerEvents="box-none" {...rest}>
|
||||||
{overlayEnabled ? (
|
{overlayEnabled ? (
|
||||||
<View style={StyleSheet.absoluteFill}>
|
<View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
|
||||||
{overlay({ style: overlayStyle })}
|
{overlay({ style: overlayStyle })}
|
||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -508,6 +517,7 @@ export default class Card extends React.Component<Props> {
|
|||||||
: gestureDirection === 'vertical'
|
: gestureDirection === 'vertical'
|
||||||
? [styles.shadowVertical, styles.shadowTop]
|
? [styles.shadowVertical, styles.shadowTop]
|
||||||
: [styles.shadowVertical, styles.shadowBottom],
|
: [styles.shadowVertical, styles.shadowBottom],
|
||||||
|
{ backgroundColor },
|
||||||
shadowStyle,
|
shadowStyle,
|
||||||
]}
|
]}
|
||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
@@ -544,7 +554,6 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
shadow: {
|
shadow: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
backgroundColor: '#fff',
|
|
||||||
shadowRadius: 5,
|
shadowRadius: 5,
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOpacity: 0.3,
|
shadowOpacity: 0.3,
|
||||||
|
|||||||
@@ -46,31 +46,63 @@ type State = {
|
|||||||
|
|
||||||
const GestureHandlerWrapper = GestureHandlerRootView ?? View;
|
const GestureHandlerWrapper = GestureHandlerRootView ?? View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two arrays with primitive values as the content.
|
||||||
|
* We need to make sure that both values and order match.
|
||||||
|
*/
|
||||||
|
const isArrayEqual = (a: any[], b: any[]) =>
|
||||||
|
a.length === b.length && a.every((it, index) => it === b[index]);
|
||||||
|
|
||||||
export default class StackView extends React.Component<Props, State> {
|
export default class StackView extends React.Component<Props, State> {
|
||||||
static getDerivedStateFromProps(
|
static getDerivedStateFromProps(
|
||||||
props: Readonly<Props>,
|
props: Readonly<Props>,
|
||||||
state: Readonly<State>
|
state: Readonly<State>
|
||||||
) {
|
) {
|
||||||
// If there was no change in routes, we don't need to compute anything
|
// If there was no change in routes, we don't need to compute anything
|
||||||
if (props.state.routes === state.previousRoutes && state.routes.length) {
|
if (
|
||||||
if (props.descriptors !== state.previousDescriptors) {
|
(props.state.routes === state.previousRoutes ||
|
||||||
const descriptors = state.routes.reduce<StackDescriptorMap>(
|
isArrayEqual(
|
||||||
(acc, route) => {
|
props.state.routes.map((r) => r.key),
|
||||||
acc[route.key] =
|
state.previousRoutes.map((r) => r.key)
|
||||||
props.descriptors[route.key] || state.descriptors[route.key];
|
)) &&
|
||||||
|
state.routes.length
|
||||||
|
) {
|
||||||
|
let routes = state.routes;
|
||||||
|
let previousRoutes = state.previousRoutes;
|
||||||
|
let descriptors = props.descriptors;
|
||||||
|
let previousDescriptors = state.previousDescriptors;
|
||||||
|
|
||||||
|
if (props.descriptors !== state.previousDescriptors) {
|
||||||
|
descriptors = state.routes.reduce<StackDescriptorMap>((acc, route) => {
|
||||||
|
acc[route.key] =
|
||||||
|
props.descriptors[route.key] || state.descriptors[route.key];
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
previousDescriptors = props.descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.state.routes !== state.previousRoutes) {
|
||||||
|
// if any route objects have changed, we should update them
|
||||||
|
const map = props.state.routes.reduce<Record<string, Route<string>>>(
|
||||||
|
(acc, route) => {
|
||||||
|
acc[route.key] = route;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
routes = state.routes.map((route) => map[route.key] || route);
|
||||||
previousDescriptors: props.descriptors,
|
previousRoutes = props.state.routes;
|
||||||
descriptors,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return {
|
||||||
|
routes,
|
||||||
|
previousRoutes,
|
||||||
|
descriptors,
|
||||||
|
previousDescriptors,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we determine which routes were added or removed to animate them
|
// Here we determine which routes were added or removed to animate them
|
||||||
|
|||||||
Reference in New Issue
Block a user