mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-25 05:18:15 +08:00
Compare commits
6 Commits
@react-nav
...
@react-nav
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68a334cc93 | ||
|
|
c110570d4c | ||
|
|
d57226fd8b | ||
|
|
c3d3748143 | ||
|
|
8002d51795 | ||
|
|
31cf19912b |
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.27](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/bottom-tabs@5.0.0-alpha.26...@react-navigation/bottom-tabs@5.0.0-alpha.27) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.26](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/bottom-tabs@5.0.0-alpha.25...@react-navigation/bottom-tabs@5.0.0-alpha.26) (2019-12-14)
|
# [5.0.0-alpha.26](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/bottom-tabs@5.0.0-alpha.25...@react-navigation/bottom-tabs@5.0.0-alpha.26) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"android",
|
"android",
|
||||||
"tab"
|
"tab"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.26",
|
"version": "5.0.0-alpha.27",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16",
|
"@react-navigation/routers": "^5.0.0-alpha.17",
|
||||||
"color": "^3.1.2"
|
"color": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.18](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/compat@5.0.0-alpha.17...@react-navigation/compat@5.0.0-alpha.18) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/compat
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.17](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/compat@5.0.0-alpha.16...@react-navigation/compat@5.0.0-alpha.17) (2019-12-11)
|
# [5.0.0-alpha.17](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/compat@5.0.0-alpha.16...@react-navigation/compat@5.0.0-alpha.17) (2019-12-11)
|
||||||
|
|
||||||
**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.0.0-alpha.17",
|
"version": "5.0.0-alpha.18",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16"
|
"@react-navigation/routers": "^5.0.0-alpha.17"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^16.9.11",
|
"@types/react": "^16.9.11",
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.0.0-alpha.28](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/core@5.0.0-alpha.27...@react-navigation/core@5.0.0-alpha.28) (2019-12-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* use Partial type for initialParam ([#206](https://github.com/react-navigation/navigation-ex/issues/206)) ([c3d3748](https://github.com/react-navigation/navigation-ex/commit/c3d374814308b0bd6d259099444f0f24593f4d7e))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add nested config in deep linking ([#210](https://github.com/react-navigation/navigation-ex/issues/210)) ([8002d51](https://github.com/react-navigation/navigation-ex/commit/8002d5179524a7211c37760a4ed45e8c12af4358)), closes [#154](https://github.com/react-navigation/navigation-ex/issues/154)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.27](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/core@5.0.0-alpha.26...@react-navigation/core@5.0.0-alpha.27) (2019-12-10)
|
# [5.0.0-alpha.27](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/core@5.0.0-alpha.26...@react-navigation/core@5.0.0-alpha.27) (2019-12-10)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/core
|
**Note:** Version bump only for package @react-navigation/core
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"react-native",
|
"react-native",
|
||||||
"react-navigation"
|
"react-navigation"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.27",
|
"version": "5.0.0-alpha.28",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -127,3 +127,238 @@ it('handles route without param', () => {
|
|||||||
it('returns undefined for invalid path', () => {
|
it('returns undefined for invalid path', () => {
|
||||||
expect(getStateFromPath('//')).toBe(undefined);
|
expect(getStateFromPath('//')).toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('converts path string to initial state with config with nested screens', () => {
|
||||||
|
expect(
|
||||||
|
getStateFromPath(
|
||||||
|
'/few/bar/sweet/apple/baz/jane?count=10&answer=42&valid=true',
|
||||||
|
{
|
||||||
|
Foo: {
|
||||||
|
Foe: 'few',
|
||||||
|
},
|
||||||
|
Bar: 'bar/:type/:fruit',
|
||||||
|
Baz: {
|
||||||
|
path: 'baz/:author',
|
||||||
|
parse: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, c => c.toUpperCase()),
|
||||||
|
count: Number,
|
||||||
|
valid: Boolean,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foe',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bar',
|
||||||
|
params: { fruit: 'apple', type: 'sweet' },
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Baz',
|
||||||
|
params: {
|
||||||
|
author: 'Jane',
|
||||||
|
count: 10,
|
||||||
|
answer: '42',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts path string to initial state with config with nested screens and unused configs', () => {
|
||||||
|
expect(
|
||||||
|
getStateFromPath('/few/baz/jane?count=10&answer=42&valid=true', {
|
||||||
|
Foo: {
|
||||||
|
Foe: 'few',
|
||||||
|
},
|
||||||
|
Baz: {
|
||||||
|
path: 'baz/:author',
|
||||||
|
parse: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, c => c.toUpperCase()),
|
||||||
|
count: Number,
|
||||||
|
valid: Boolean,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foe',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Baz',
|
||||||
|
params: {
|
||||||
|
author: 'Jane',
|
||||||
|
count: 10,
|
||||||
|
answer: '42',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles parse in nested object with parse in it', () => {
|
||||||
|
expect(
|
||||||
|
getStateFromPath(
|
||||||
|
'/bar/sweet/apple/few/bis/jane?count=10&answer=42&valid=true',
|
||||||
|
{
|
||||||
|
Foo: {
|
||||||
|
Foe: 'few',
|
||||||
|
},
|
||||||
|
Bar: 'bar/:type/:fruit',
|
||||||
|
Baz: {
|
||||||
|
Bis: {
|
||||||
|
path: 'bis/:author',
|
||||||
|
parse: {
|
||||||
|
author: (author: string) =>
|
||||||
|
author.replace(/^\w/, c => c.toUpperCase()),
|
||||||
|
count: Number,
|
||||||
|
valid: Boolean,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bar',
|
||||||
|
params: { fruit: 'apple', type: 'sweet' },
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foe',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Baz',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bis',
|
||||||
|
params: {
|
||||||
|
author: 'Jane',
|
||||||
|
count: 10,
|
||||||
|
answer: '42',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles parse in nested object for second route depth', () => {
|
||||||
|
expect(
|
||||||
|
getStateFromPath('/baz', {
|
||||||
|
Foo: {
|
||||||
|
path: 'foo',
|
||||||
|
Foe: 'foe',
|
||||||
|
Bar: {
|
||||||
|
Baz: 'baz',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bar',
|
||||||
|
state: {
|
||||||
|
routes: [{ name: 'Baz' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles parse in nested object for second route depth and and path and parse in roots', () => {
|
||||||
|
expect(
|
||||||
|
getStateFromPath('/baz', {
|
||||||
|
Foo: {
|
||||||
|
path: 'foo/:id',
|
||||||
|
parse: {
|
||||||
|
id: Number,
|
||||||
|
},
|
||||||
|
Foe: 'foe',
|
||||||
|
Bar: {
|
||||||
|
path: 'bar/:id',
|
||||||
|
parse: {
|
||||||
|
id: Number,
|
||||||
|
},
|
||||||
|
Baz: 'baz',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Foo',
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'Bar',
|
||||||
|
state: {
|
||||||
|
routes: [{ name: 'Baz' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import escape from 'escape-string-regexp';
|
import escape from 'escape-string-regexp';
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
import { NavigationState, PartialState } from './types';
|
import { NavigationState, PartialState, InitialState } from './types';
|
||||||
|
|
||||||
type ParseConfig = Record<string, (value: string) => any>;
|
type ParseConfig = Record<string, (value: string) => any>;
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
[routeName: string]: string | { path: string; parse?: ParseConfig };
|
[routeName: string]: string | { path: string; parse?: ParseConfig } | Options;
|
||||||
|
};
|
||||||
|
|
||||||
|
type RouteConfig = {
|
||||||
|
match: RegExp;
|
||||||
|
pattern: string;
|
||||||
|
routeNames: string[];
|
||||||
|
parse: Record<string, (value: string) => any> | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,27 +38,10 @@ export default function getStateFromPath(
|
|||||||
path: string,
|
path: string,
|
||||||
options: Options = {}
|
options: Options = {}
|
||||||
): PartialState<NavigationState> | undefined {
|
): PartialState<NavigationState> | undefined {
|
||||||
// Create a normalized config array which will be easier to use
|
// Create a normalized configs array which will be easier to use
|
||||||
const routeConfig = Object.keys(options).map(key => {
|
const configs = ([] as RouteConfig[]).concat(
|
||||||
const pattern =
|
...Object.keys(options).map(key => createNormalizedConfigs(key, options))
|
||||||
typeof options[key] === 'string'
|
);
|
||||||
? (options[key] as string)
|
|
||||||
: (options[key] as { path: string }).path;
|
|
||||||
|
|
||||||
// Create a regex from the provided path pattern
|
|
||||||
// With the pattern, we can match segements containing params and extract them
|
|
||||||
const match = new RegExp(
|
|
||||||
'^' + escape(pattern).replace(/:[a-z0-9]+/gi, '([^/]+)') + '/?'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
match,
|
|
||||||
pattern,
|
|
||||||
routeName: key,
|
|
||||||
// @ts-ignore
|
|
||||||
parse: options[key].parse,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
let result: PartialState<NavigationState> | undefined;
|
let result: PartialState<NavigationState> | undefined;
|
||||||
let current: PartialState<NavigationState> | undefined;
|
let current: PartialState<NavigationState> | undefined;
|
||||||
@@ -62,16 +52,16 @@ export default function getStateFromPath(
|
|||||||
.replace(/\?.*/, ''); // Remove query params which we will handle later
|
.replace(/\?.*/, ''); // Remove query params which we will handle later
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
let routeName;
|
let routeNames;
|
||||||
let params;
|
let params;
|
||||||
|
|
||||||
// Go through all configs, and see if the next path segment matches our regex
|
// Go through all configs, and see if the next path segment matches our regex
|
||||||
for (const config of routeConfig) {
|
for (const config of configs) {
|
||||||
const match = remaining.match(config.match);
|
const match = remaining.match(config.match);
|
||||||
|
|
||||||
// If our regex matches, we need to extract params from the path
|
// If our regex matches, we need to extract params from the path
|
||||||
if (match) {
|
if (match) {
|
||||||
routeName = config.routeName;
|
routeNames = config.routeNames;
|
||||||
|
|
||||||
const paramPatterns = config.pattern
|
const paramPatterns = config.pattern
|
||||||
.split('/')
|
.split('/')
|
||||||
@@ -99,20 +89,54 @@ export default function getStateFromPath(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we hadn't matched any segments earlier, use the path as route name
|
// If we hadn't matched any segments earlier, use the path as route name
|
||||||
if (routeName === undefined) {
|
if (routeNames === undefined) {
|
||||||
const segments = remaining.split('/');
|
const segments = remaining.split('/');
|
||||||
|
|
||||||
routeName = decodeURIComponent(segments[0]);
|
routeNames = [decodeURIComponent(segments[0])];
|
||||||
segments.shift();
|
segments.shift();
|
||||||
remaining = segments.join('/');
|
remaining = segments.join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = {
|
let state: InitialState;
|
||||||
routes: [{ name: routeName, params }],
|
|
||||||
};
|
if (routeNames.length === 1) {
|
||||||
|
state = {
|
||||||
|
routes: [
|
||||||
|
{ name: routeNames.shift() as string, ...(params && { params }) },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
state = {
|
||||||
|
routes: [{ name: routeNames.shift() as string, state: { routes: [] } }],
|
||||||
|
};
|
||||||
|
|
||||||
|
let helper = state.routes[0].state as InitialState;
|
||||||
|
let routeName;
|
||||||
|
|
||||||
|
while ((routeName = routeNames.shift())) {
|
||||||
|
if (routeNames.length === 0) {
|
||||||
|
helper.routes.push({
|
||||||
|
name: routeName,
|
||||||
|
...(params && { params }),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
helper.routes[0] = {
|
||||||
|
name: routeName,
|
||||||
|
state: {
|
||||||
|
routes: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
helper = helper.routes[0].state as InitialState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (current) {
|
if (current) {
|
||||||
// The state should be nested inside the route we parsed before
|
// The state should be nested inside the deepest route we parsed before
|
||||||
|
while (current.routes[0].state) {
|
||||||
|
current = current.routes[0].state;
|
||||||
|
}
|
||||||
|
|
||||||
current.routes[0].state = state;
|
current.routes[0].state = state;
|
||||||
} else {
|
} else {
|
||||||
result = state;
|
result = state;
|
||||||
@@ -128,17 +152,20 @@ export default function getStateFromPath(
|
|||||||
const query = path.split('?')[1];
|
const query = path.split('?')[1];
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
|
while (current.routes[0].state) {
|
||||||
|
// The query params apply to the deepest route
|
||||||
|
current = current.routes[0].state;
|
||||||
|
}
|
||||||
|
|
||||||
const route = current.routes[0];
|
const route = current.routes[0];
|
||||||
|
|
||||||
const params = queryString.parse(query);
|
const params = queryString.parse(query);
|
||||||
const config = options[route.name]
|
const parseFunction = findParseConfigForRoute(route.name, options);
|
||||||
? (options[route.name] as { parse?: ParseConfig }).parse
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
if (config) {
|
if (parseFunction) {
|
||||||
Object.keys(params).forEach(name => {
|
Object.keys(params).forEach(name => {
|
||||||
if (config[name] && typeof params[name] === 'string') {
|
if (parseFunction[name] && typeof params[name] === 'string') {
|
||||||
params[name] = config[name](params[name] as string);
|
params[name] = parseFunction[name](params[name] as string);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -148,3 +175,89 @@ export default function getStateFromPath(
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNormalizedConfigs(
|
||||||
|
key: string,
|
||||||
|
routeConfig: Options,
|
||||||
|
routeNames: string[] = []
|
||||||
|
): RouteConfig[] {
|
||||||
|
const configs = [];
|
||||||
|
|
||||||
|
routeNames.push(key);
|
||||||
|
|
||||||
|
const value = routeConfig[key];
|
||||||
|
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
// If a string is specified as the value of the key(e.g. Foo: '/path'), use it as the pattern
|
||||||
|
configs.push(createConfigItem(routeNames, value));
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
|
// if an object is specified as the value (e.g. Foo: { ... }),
|
||||||
|
// it could have config object and optionally nested config
|
||||||
|
Object.keys(value).forEach(nestedKey => {
|
||||||
|
if (nestedKey === 'path') {
|
||||||
|
configs.push(
|
||||||
|
createConfigItem(
|
||||||
|
routeNames,
|
||||||
|
value[nestedKey] as string,
|
||||||
|
value.parse ? (value.parse as ParseConfig) : undefined
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else if (nestedKey === 'parse') {
|
||||||
|
// We handle custom parse function when a `path` is specified (in nestedKey === path)
|
||||||
|
} else {
|
||||||
|
// If the name of the key is not `path` or `parse`, it's a nested config for route
|
||||||
|
// So we need to traverse into it and collect the configs
|
||||||
|
const result = createNormalizedConfigs(
|
||||||
|
nestedKey,
|
||||||
|
routeConfig[key] as Options,
|
||||||
|
routeNames
|
||||||
|
);
|
||||||
|
|
||||||
|
configs.push(...result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
routeNames.pop();
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createConfigItem(
|
||||||
|
routeNames: string[],
|
||||||
|
pattern: string,
|
||||||
|
parse?: ParseConfig
|
||||||
|
): RouteConfig {
|
||||||
|
const match = new RegExp(
|
||||||
|
'^' + escape(pattern).replace(/:[a-z0-9]+/gi, '([^/]+)') + '/?'
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
match,
|
||||||
|
pattern,
|
||||||
|
// The routeNames array is mutated, so copy it to keep the current state
|
||||||
|
routeNames: [...routeNames],
|
||||||
|
parse,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function findParseConfigForRoute(
|
||||||
|
routeName: string,
|
||||||
|
config: Options
|
||||||
|
): ParseConfig | undefined {
|
||||||
|
if (config[routeName]) {
|
||||||
|
return (config[routeName] as { parse?: ParseConfig }).parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const name in config) {
|
||||||
|
if (typeof config[name] === 'object') {
|
||||||
|
const parse = findParseConfigForRoute(routeName, config[name] as Options);
|
||||||
|
|
||||||
|
if (parse) {
|
||||||
|
return parse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ export type RouteConfig<
|
|||||||
/**
|
/**
|
||||||
* Initial params object for the route.
|
* Initial params object for the route.
|
||||||
*/
|
*/
|
||||||
initialParams?: ParamList[RouteName];
|
initialParams?: Partial<ParamList[RouteName]>;
|
||||||
} & (
|
} & (
|
||||||
| {
|
| {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.29](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/drawer@5.0.0-alpha.28...@react-navigation/drawer@5.0.0-alpha.29) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.28](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/drawer@5.0.0-alpha.27...@react-navigation/drawer@5.0.0-alpha.28) (2019-12-14)
|
# [5.0.0-alpha.28](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/drawer@5.0.0-alpha.27...@react-navigation/drawer@5.0.0-alpha.28) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"material",
|
"material",
|
||||||
"drawer"
|
"drawer"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.28",
|
"version": "5.0.0-alpha.29",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16",
|
"@react-navigation/routers": "^5.0.0-alpha.17",
|
||||||
"color": "^3.1.2"
|
"color": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.26](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.25...@react-navigation/material-bottom-tabs@5.0.0-alpha.26) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.25](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.24...@react-navigation/material-bottom-tabs@5.0.0-alpha.25) (2019-12-14)
|
# [5.0.0-alpha.25](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.24...@react-navigation/material-bottom-tabs@5.0.0-alpha.25) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"material",
|
"material",
|
||||||
"tab"
|
"tab"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.25",
|
"version": "5.0.0-alpha.26",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16"
|
"@react-navigation/routers": "^5.0.0-alpha.17"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.7.0",
|
"@react-native-community/bob": "^0.7.0",
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.24](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-top-tabs@5.0.0-alpha.23...@react-navigation/material-top-tabs@5.0.0-alpha.24) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.23](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-top-tabs@5.0.0-alpha.22...@react-navigation/material-top-tabs@5.0.0-alpha.23) (2019-12-14)
|
# [5.0.0-alpha.23](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-top-tabs@5.0.0-alpha.22...@react-navigation/material-top-tabs@5.0.0-alpha.23) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"material",
|
"material",
|
||||||
"tab"
|
"tab"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.23",
|
"version": "5.0.0-alpha.24",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16",
|
"@react-navigation/routers": "^5.0.0-alpha.17",
|
||||||
"color": "^3.1.2"
|
"color": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.18](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.17...@react-navigation/native-stack@5.0.0-alpha.18) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.17](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.16...@react-navigation/native-stack@5.0.0-alpha.17) (2019-12-14)
|
# [5.0.0-alpha.17](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.16...@react-navigation/native-stack@5.0.0-alpha.17) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Stack navigator for React Native using native primitives for navigation. Uses [`react-native-screens`](https://github.com/kmagiera/react-native-screens) under the hood.
|
Stack navigator for React Native using native primitives for navigation. Uses [`react-native-screens`](https://github.com/kmagiera/react-native-screens) under the hood.
|
||||||
|
|
||||||
Expo is currently not supported as it includes an older version of `react-native-screens`.
|
Expo SDK 35 and lower is not supported as it includes an older version of `react-native-screens`.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -11,12 +11,30 @@ Open a Terminal in your project's folder and run,
|
|||||||
```sh
|
```sh
|
||||||
yarn add @react-navigation/native @react-navigation/native-stack
|
yarn add @react-navigation/native @react-navigation/native-stack
|
||||||
```
|
```
|
||||||
|
Or with npm
|
||||||
|
|
||||||
Now we need to install [`react-native-screens`](https://github.com/kmagiera/react-native-screens).
|
```sh
|
||||||
|
npm install --save @react-navigation/native @react-navigation/native-stack
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using Expo, to ensure that you get the compatible versions of the libraries, run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
expo install react-native-screens
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are not using Expo, run the following:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn add react-native-screens
|
yarn add react-native-screens
|
||||||
```
|
```
|
||||||
|
Or with npm
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --save react-native-screens
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using Expo, you are done. Otherwise, continue to the next steps.
|
||||||
|
|
||||||
To complete the linking on iOS, make sure you have [Cocoapods](https://cocoapods.org/) installed. Then run:
|
To complete the linking on iOS, make sure you have [Cocoapods](https://cocoapods.org/) installed. Then run:
|
||||||
|
|
||||||
@@ -36,9 +54,9 @@ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
|||||||
Make sure to enable `react-native-screens`. This needs to be done before our app renders. To do it, add the following code in your entry file (e.g. `App.js`):
|
Make sure to enable `react-native-screens`. This needs to be done before our app renders. To do it, add the following code in your entry file (e.g. `App.js`):
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { useScreens } from 'react-native-screens';
|
import { enableScreens } from 'react-native-screens';
|
||||||
|
|
||||||
useScreens();
|
enableScreens();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"react-native",
|
"react-native",
|
||||||
"react-navigation"
|
"react-navigation"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.17",
|
"version": "5.0.0-alpha.18",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16"
|
"@react-navigation/routers": "^5.0.0-alpha.17"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.7.0",
|
"@react-native-community/bob": "^0.7.0",
|
||||||
|
|||||||
@@ -3,6 +3,17 @@
|
|||||||
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.0.0-alpha.20](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native@5.0.0-alpha.19...@react-navigation/native@5.0.0-alpha.20) (2019-12-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add nested config in deep linking ([#210](https://github.com/react-navigation/navigation-ex/issues/210)) ([8002d51](https://github.com/react-navigation/navigation-ex/commit/8002d5179524a7211c37760a4ed45e8c12af4358)), closes [#154](https://github.com/react-navigation/navigation-ex/issues/154)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.19](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native@5.0.0-alpha.18...@react-navigation/native@5.0.0-alpha.19) (2019-12-14)
|
# [5.0.0-alpha.19](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native@5.0.0-alpha.18...@react-navigation/native@5.0.0-alpha.19) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"ios",
|
"ios",
|
||||||
"android"
|
"android"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.19",
|
"version": "5.0.0-alpha.20",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^5.0.0-alpha.27"
|
"@react-navigation/core": "^5.0.0-alpha.28"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.7.0",
|
"@react-native-community/bob": "^0.7.0",
|
||||||
|
|||||||
@@ -3,15 +3,11 @@ import { Linking } from 'react-native';
|
|||||||
import {
|
import {
|
||||||
getStateFromPath as getStateFromPathDefault,
|
getStateFromPath as getStateFromPathDefault,
|
||||||
NavigationContainerRef,
|
NavigationContainerRef,
|
||||||
NavigationState,
|
|
||||||
PartialState,
|
|
||||||
} from '@react-navigation/core';
|
} from '@react-navigation/core';
|
||||||
|
|
||||||
type Config = {
|
type GetStateFromPath = typeof getStateFromPathDefault;
|
||||||
[routeName: string]:
|
|
||||||
| string
|
type Config = Parameters<GetStateFromPath>[1];
|
||||||
| { path: string; parse?: Record<string, (value: string) => any> };
|
|
||||||
};
|
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
/**
|
/**
|
||||||
@@ -36,10 +32,7 @@ type Options = {
|
|||||||
/**
|
/**
|
||||||
* Custom function to parse the URL object to a valid navigation state (advanced).
|
* Custom function to parse the URL object to a valid navigation state (advanced).
|
||||||
*/
|
*/
|
||||||
getStateFromPath?: (
|
getStateFromPath?: GetStateFromPath;
|
||||||
path: string,
|
|
||||||
options?: Config
|
|
||||||
) => PartialState<NavigationState> | undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function useLinking(
|
export default function useLinking(
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
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.0.0-alpha.17](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/routers@5.0.0-alpha.16...@react-navigation/routers@5.0.0-alpha.17) (2019-12-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/routers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.16](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/routers@5.0.0-alpha.15...@react-navigation/routers@5.0.0-alpha.16) (2019-12-11)
|
# [5.0.0-alpha.16](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/routers@5.0.0-alpha.15...@react-navigation/routers@5.0.0-alpha.16) (2019-12-11)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/routers
|
**Note:** Version bump only for package @react-navigation/routers
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"react-native",
|
"react-native",
|
||||||
"react-navigation"
|
"react-navigation"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.16",
|
"version": "5.0.0-alpha.17",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^5.0.0-alpha.27",
|
"@react-navigation/core": "^5.0.0-alpha.28",
|
||||||
"shortid": "^2.2.15"
|
"shortid": "^2.2.15"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,17 @@
|
|||||||
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.0.0-alpha.45](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.44...@react-navigation/stack@5.0.0-alpha.45) (2019-12-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* disable style interpolation for card when animation is disabled ([c110570](https://github.com/react-navigation/navigation-ex/commit/c110570d4c89a38336f19403e6f2d0870868620e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [5.0.0-alpha.44](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.43...@react-navigation/stack@5.0.0-alpha.44) (2019-12-14)
|
# [5.0.0-alpha.44](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.43...@react-navigation/stack@5.0.0-alpha.44) (2019-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"android",
|
"android",
|
||||||
"stack"
|
"stack"
|
||||||
],
|
],
|
||||||
"version": "5.0.0-alpha.44",
|
"version": "5.0.0-alpha.45",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -33,11 +33,13 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/routers": "^5.0.0-alpha.16"
|
"@react-navigation/routers": "^5.0.0-alpha.17",
|
||||||
|
"color": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.7.0",
|
"@react-native-community/bob": "^0.7.0",
|
||||||
"@react-native-community/masked-view": "^0.1.5",
|
"@react-native-community/masked-view": "^0.1.5",
|
||||||
|
"@types/color": "^3.0.0",
|
||||||
"@types/react": "^16.9.11",
|
"@types/react": "^16.9.11",
|
||||||
"@types/react-native": "^0.60.22",
|
"@types/react-native": "^0.60.22",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.0",
|
||||||
|
|||||||
@@ -273,3 +273,7 @@ export function forScaleFromCenterAndroid({
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function forNoAnimation(): StackCardInterpolatedStyle {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|||||||
@@ -271,18 +271,14 @@ export type StackNavigationOptions = StackHeaderOptions &
|
|||||||
* Defaults to `true` on Android and `false` on iOS.
|
* Defaults to `true` on Android and `false` on iOS.
|
||||||
*/
|
*/
|
||||||
cardOverlayEnabled?: boolean;
|
cardOverlayEnabled?: boolean;
|
||||||
/**
|
|
||||||
* Whether to use a transparent background for the card instead of a white one.
|
|
||||||
* This is useful to implement things like modal dialogs where the previous scene should still be visible underneath the current one.
|
|
||||||
* Defaults to `false`.
|
|
||||||
*
|
|
||||||
* If you use [`react-native-screens`](https://github.com/kmagiera/react-native-screens),
|
|
||||||
* you should also specify `mode: 'modal'` in the stack view config so previous screens aren't detached.
|
|
||||||
*/
|
|
||||||
cardTransparent?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* Style object for the card in stack.
|
* Style object for the card in stack.
|
||||||
* You can provide a custom background color to use instead of the default background here.
|
* You can provide a custom background color to use instead of the default background here.
|
||||||
|
*
|
||||||
|
* You can also specify `{ backgroundColor: 'transparent' }` to make the previous screen visible underneath.
|
||||||
|
* This is useful to implement things like modal dialogs.
|
||||||
|
* If you use [`react-native-screens`](https://github.com/kmagiera/react-native-screens), you should also specify `mode: 'modal'`
|
||||||
|
* in the stack view config when using a transparent background so previous screens aren't detached.
|
||||||
*/
|
*/
|
||||||
cardStyle?: StyleProp<ViewStyle>;
|
cardStyle?: StyleProp<ViewStyle>;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
import Animated, { Easing } from 'react-native-reanimated';
|
import Animated, { Easing } from 'react-native-reanimated';
|
||||||
import { PanGestureHandler } from 'react-native-gesture-handler';
|
import { PanGestureHandler } from 'react-native-gesture-handler';
|
||||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
import { EdgeInsets } from 'react-native-safe-area-context';
|
||||||
|
import Color from 'color';
|
||||||
import animate, { Binary } from './CardAnimation';
|
import animate, { Binary } from './CardAnimation';
|
||||||
import PointerEventsView from './PointerEventsView';
|
import PointerEventsView from './PointerEventsView';
|
||||||
import memoize from '../../utils/memoize';
|
import memoize from '../../utils/memoize';
|
||||||
@@ -30,7 +31,6 @@ type Props = ViewProps & {
|
|||||||
index: number;
|
index: number;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
closing?: boolean;
|
closing?: boolean;
|
||||||
transparent?: boolean;
|
|
||||||
next?: Animated.Node<number>;
|
next?: Animated.Node<number>;
|
||||||
current: Animated.Value<number>;
|
current: Animated.Value<number>;
|
||||||
layout: Layout;
|
layout: Layout;
|
||||||
@@ -758,7 +758,6 @@ export default class Card extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
active,
|
active,
|
||||||
transparent,
|
|
||||||
styleInterpolator,
|
styleInterpolator,
|
||||||
index,
|
index,
|
||||||
current,
|
current,
|
||||||
@@ -813,6 +812,11 @@ export default class Card extends React.Component<Props> {
|
|||||||
: this.handleGestureEventHorizontal
|
: this.handleGestureEventHorizontal
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
|
const { backgroundColor } = StyleSheet.flatten(contentStyle || {});
|
||||||
|
const isTransparent = backgroundColor
|
||||||
|
? Color(backgroundColor).alpha() === 0
|
||||||
|
: false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StackGestureContext.Provider value={this.gestureRef}>
|
<StackGestureContext.Provider value={this.gestureRef}>
|
||||||
<View pointerEvents="box-none" {...rest}>
|
<View pointerEvents="box-none" {...rest}>
|
||||||
@@ -838,7 +842,7 @@ export default class Card extends React.Component<Props> {
|
|||||||
{...this.gestureActivationCriteria()}
|
{...this.gestureActivationCriteria()}
|
||||||
>
|
>
|
||||||
<Animated.View style={[styles.container, cardStyle]}>
|
<Animated.View style={[styles.container, cardStyle]}>
|
||||||
{shadowEnabled && shadowStyle && !transparent ? (
|
{shadowEnabled && shadowStyle && !isTransparent ? (
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={[
|
style={[
|
||||||
styles.shadow,
|
styles.shadow,
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ type Props = TransitionPreset & {
|
|||||||
safeAreaInsetRight: number;
|
safeAreaInsetRight: number;
|
||||||
safeAreaInsetBottom: number;
|
safeAreaInsetBottom: number;
|
||||||
safeAreaInsetLeft: number;
|
safeAreaInsetLeft: number;
|
||||||
cardTransparent?: boolean;
|
|
||||||
cardOverlayEnabled?: boolean;
|
cardOverlayEnabled?: boolean;
|
||||||
cardShadowEnabled?: boolean;
|
cardShadowEnabled?: boolean;
|
||||||
cardStyle?: StyleProp<ViewStyle>;
|
cardStyle?: StyleProp<ViewStyle>;
|
||||||
|
animationEnabled?: boolean;
|
||||||
getPreviousRoute: (props: {
|
getPreviousRoute: (props: {
|
||||||
route: Route<string>;
|
route: Route<string>;
|
||||||
}) => Route<string> | undefined;
|
}) => Route<string> | undefined;
|
||||||
@@ -59,7 +59,6 @@ export default function CardContainer({
|
|||||||
cardShadowEnabled,
|
cardShadowEnabled,
|
||||||
cardStyle,
|
cardStyle,
|
||||||
cardStyleInterpolator,
|
cardStyleInterpolator,
|
||||||
cardTransparent,
|
|
||||||
closing,
|
closing,
|
||||||
current,
|
current,
|
||||||
floatingHeaderHeight,
|
floatingHeaderHeight,
|
||||||
@@ -128,7 +127,6 @@ export default function CardContainer({
|
|||||||
<Card
|
<Card
|
||||||
index={index}
|
index={index}
|
||||||
active={active}
|
active={active}
|
||||||
transparent={cardTransparent}
|
|
||||||
gestureDirection={gestureDirection}
|
gestureDirection={gestureDirection}
|
||||||
layout={layout}
|
layout={layout}
|
||||||
insets={insets}
|
insets={insets}
|
||||||
@@ -155,12 +153,7 @@ export default function CardContainer({
|
|||||||
? { marginTop: floatingHeaderHeight }
|
? { marginTop: floatingHeaderHeight }
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
contentStyle={[
|
contentStyle={[{ backgroundColor: colors.background }, cardStyle]}
|
||||||
{
|
|
||||||
backgroundColor: cardTransparent ? 'transparent' : colors.background,
|
|
||||||
},
|
|
||||||
cardStyle,
|
|
||||||
]}
|
|
||||||
style={StyleSheet.absoluteFill}
|
style={StyleSheet.absoluteFill}
|
||||||
>
|
>
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import {
|
|||||||
DefaultTransition,
|
DefaultTransition,
|
||||||
ModalTransition,
|
ModalTransition,
|
||||||
} from '../../TransitionConfigs/TransitionPresets';
|
} from '../../TransitionConfigs/TransitionPresets';
|
||||||
import { forNoAnimation } from '../../TransitionConfigs/HeaderStyleInterpolators';
|
import { forNoAnimation as forNoAnimationHeader } from '../../TransitionConfigs/HeaderStyleInterpolators';
|
||||||
|
import { forNoAnimation as forNoAnimationCard } from '../../TransitionConfigs/CardStyleInterpolators';
|
||||||
import {
|
import {
|
||||||
Layout,
|
Layout,
|
||||||
StackHeaderMode,
|
StackHeaderMode,
|
||||||
@@ -314,7 +315,7 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
if (headerMode === 'screen') {
|
if (headerMode === 'screen') {
|
||||||
defaultTransitionPreset = {
|
defaultTransitionPreset = {
|
||||||
...defaultTransitionPreset,
|
...defaultTransitionPreset,
|
||||||
headerStyleInterpolator: forNoAnimation,
|
headerStyleInterpolator: forNoAnimationHeader,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,15 +355,17 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
safeAreaInsets,
|
safeAreaInsets,
|
||||||
headerShown,
|
headerShown,
|
||||||
headerTransparent,
|
headerTransparent,
|
||||||
cardTransparent,
|
|
||||||
cardShadowEnabled,
|
cardShadowEnabled,
|
||||||
cardOverlayEnabled,
|
cardOverlayEnabled,
|
||||||
cardStyle,
|
cardStyle,
|
||||||
|
animationEnabled,
|
||||||
gestureResponseDistance,
|
gestureResponseDistance,
|
||||||
gestureVelocityImpact,
|
gestureVelocityImpact,
|
||||||
gestureDirection = defaultTransitionPreset.gestureDirection,
|
gestureDirection = defaultTransitionPreset.gestureDirection,
|
||||||
transitionSpec = defaultTransitionPreset.transitionSpec,
|
transitionSpec = defaultTransitionPreset.transitionSpec,
|
||||||
cardStyleInterpolator = defaultTransitionPreset.cardStyleInterpolator,
|
cardStyleInterpolator = animationEnabled === false
|
||||||
|
? forNoAnimationCard
|
||||||
|
: defaultTransitionPreset.cardStyleInterpolator,
|
||||||
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
||||||
} = scene.descriptor
|
} = scene.descriptor
|
||||||
? scene.descriptor.options
|
? scene.descriptor.options
|
||||||
@@ -385,8 +388,11 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
|
|
||||||
if (nextScene) {
|
if (nextScene) {
|
||||||
const {
|
const {
|
||||||
|
animationEnabled,
|
||||||
transitionSpec = defaultTransitionPreset.transitionSpec,
|
transitionSpec = defaultTransitionPreset.transitionSpec,
|
||||||
cardStyleInterpolator = defaultTransitionPreset.cardStyleInterpolator,
|
cardStyleInterpolator = animationEnabled === false
|
||||||
|
? forNoAnimationCard
|
||||||
|
: defaultTransitionPreset.cardStyleInterpolator,
|
||||||
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
||||||
} = nextScene.descriptor
|
} = nextScene.descriptor
|
||||||
? nextScene.descriptor.options
|
? nextScene.descriptor.options
|
||||||
@@ -429,10 +435,10 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
safeAreaInsetRight={safeAreaInsetRight}
|
safeAreaInsetRight={safeAreaInsetRight}
|
||||||
safeAreaInsetBottom={safeAreaInsetBottom}
|
safeAreaInsetBottom={safeAreaInsetBottom}
|
||||||
safeAreaInsetLeft={safeAreaInsetLeft}
|
safeAreaInsetLeft={safeAreaInsetLeft}
|
||||||
cardTransparent={cardTransparent}
|
|
||||||
cardOverlayEnabled={cardOverlayEnabled}
|
cardOverlayEnabled={cardOverlayEnabled}
|
||||||
cardShadowEnabled={cardShadowEnabled}
|
cardShadowEnabled={cardShadowEnabled}
|
||||||
cardStyle={cardStyle}
|
cardStyle={cardStyle}
|
||||||
|
animationEnabled={animationEnabled}
|
||||||
onPageChangeStart={onPageChangeStart}
|
onPageChangeStart={onPageChangeStart}
|
||||||
onPageChangeConfirm={onPageChangeConfirm}
|
onPageChangeConfirm={onPageChangeConfirm}
|
||||||
onPageChangeCancel={onPageChangeCancel}
|
onPageChangeCancel={onPageChangeCancel}
|
||||||
|
|||||||
Reference in New Issue
Block a user