@react-navigation/core 7.17.2 → 7.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/StaticNavigation.js +0 -19
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/checkSerializable.js +11 -4
- package/lib/module/checkSerializable.js.map +1 -1
- package/lib/module/getActionFromState.js +15 -2
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getStateFromPath.js +11 -16
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +55 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useEventEmitter.js +28 -29
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +38 -40
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useRouteCache.js +2 -1
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +2 -63
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/checkSerializable.d.ts +5 -3
- package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
- package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +102 -2
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/StaticNavigation.tsx +1 -91
- package/src/checkSerializable.tsx +22 -12
- package/src/getActionFromState.tsx +20 -4
- package/src/getStateFromPath.tsx +23 -20
- package/src/index.tsx +0 -1
- package/src/types.tsx +138 -4
- package/src/useEventEmitter.tsx +33 -38
- package/src/useNavigationBuilder.tsx +59 -65
- package/src/useRouteCache.tsx +2 -1
package/src/StaticNavigation.tsx
CHANGED
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
DefaultNavigatorOptions,
|
|
7
7
|
EventMapBase,
|
|
8
8
|
NavigationListBase,
|
|
9
|
-
NavigatorScreenParams,
|
|
10
9
|
NavigatorTypeBagBase,
|
|
11
10
|
PathConfig,
|
|
12
11
|
RouteConfigComponent,
|
|
@@ -15,77 +14,7 @@ import type {
|
|
|
15
14
|
} from './types';
|
|
16
15
|
import { useRoute } from './useRoute';
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
* Flatten a type to remove all type alias names, unions etc.
|
|
20
|
-
* This will show a plain object when hovering over the type.
|
|
21
|
-
*/
|
|
22
|
-
type FlatType<T> = { [K in keyof T]: T[K] } & {};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* keyof T doesn't work for union types. We can use distributive conditional types instead.
|
|
26
|
-
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
|
|
27
|
-
*/
|
|
28
|
-
type KeysOf<T> = T extends {} ? keyof T : never;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* We get a union type when using keyof, but we want an intersection instead.
|
|
32
|
-
* https://stackoverflow.com/a/50375286/1665026
|
|
33
|
-
*/
|
|
34
|
-
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
35
|
-
k: infer I
|
|
36
|
-
) => void
|
|
37
|
-
? I
|
|
38
|
-
: never;
|
|
39
|
-
|
|
40
|
-
type UnknownToUndefined<T> = unknown extends T ? undefined : T;
|
|
41
|
-
|
|
42
|
-
type ParamsForScreenComponent<T> = T extends {
|
|
43
|
-
screen: React.ComponentType<{ route: { params: infer P } }>;
|
|
44
|
-
}
|
|
45
|
-
? P
|
|
46
|
-
: T extends React.ComponentType<{ route: { params: infer P } }>
|
|
47
|
-
? P
|
|
48
|
-
: undefined;
|
|
49
|
-
|
|
50
|
-
type ParamsForScreen<T> = T extends {
|
|
51
|
-
screen: { config: StaticConfig<NavigatorTypeBagBase> };
|
|
52
|
-
}
|
|
53
|
-
? NavigatorScreenParams<StaticParamList<T['screen']>> | undefined
|
|
54
|
-
: T extends { config: StaticConfig<NavigatorTypeBagBase> }
|
|
55
|
-
? NavigatorScreenParams<StaticParamList<T>> | undefined
|
|
56
|
-
: UnknownToUndefined<ParamsForScreenComponent<T>>;
|
|
57
|
-
|
|
58
|
-
type ParamListForScreens<Screens> = {
|
|
59
|
-
[Key in KeysOf<Screens>]: ParamsForScreen<Screens[Key]>;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
type ParamListForGroups<
|
|
63
|
-
Groups extends
|
|
64
|
-
| Readonly<{
|
|
65
|
-
[key: string]: {
|
|
66
|
-
screens: StaticConfigScreens<
|
|
67
|
-
ParamListBase,
|
|
68
|
-
NavigationState,
|
|
69
|
-
{},
|
|
70
|
-
EventMapBase,
|
|
71
|
-
any
|
|
72
|
-
>;
|
|
73
|
-
};
|
|
74
|
-
}>
|
|
75
|
-
| undefined,
|
|
76
|
-
> = Groups extends {
|
|
77
|
-
[key: string]: {
|
|
78
|
-
screens: StaticConfigScreens<
|
|
79
|
-
ParamListBase,
|
|
80
|
-
NavigationState,
|
|
81
|
-
{},
|
|
82
|
-
EventMapBase,
|
|
83
|
-
any
|
|
84
|
-
>;
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
? ParamListForScreens<UnionToIntersection<Groups[keyof Groups]['screens']>>
|
|
88
|
-
: {};
|
|
17
|
+
export type { StaticParamList } from './types';
|
|
89
18
|
|
|
90
19
|
type StaticRouteConfig<
|
|
91
20
|
ParamList extends ParamListBase,
|
|
@@ -287,25 +216,6 @@ export type StaticScreenProps<T extends Record<string, unknown> | undefined> = {
|
|
|
287
216
|
};
|
|
288
217
|
};
|
|
289
218
|
|
|
290
|
-
/**
|
|
291
|
-
* Infer the param list from the static navigation config.
|
|
292
|
-
*/
|
|
293
|
-
export type StaticParamList<
|
|
294
|
-
T extends {
|
|
295
|
-
readonly config: {
|
|
296
|
-
readonly screens?: Record<string, any>;
|
|
297
|
-
readonly groups?: {
|
|
298
|
-
[key: string]: {
|
|
299
|
-
screens: Record<string, any>;
|
|
300
|
-
};
|
|
301
|
-
};
|
|
302
|
-
};
|
|
303
|
-
},
|
|
304
|
-
> = FlatType<
|
|
305
|
-
ParamListForScreens<T['config']['screens']> &
|
|
306
|
-
ParamListForGroups<T['config']['groups']>
|
|
307
|
-
>;
|
|
308
|
-
|
|
309
219
|
type StaticNavigationBase = {
|
|
310
220
|
config: StaticConfig<NavigatorTypeBagBase>;
|
|
311
221
|
getComponent: () => React.ComponentType<{}>;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
o: { [key: string]: any },
|
|
3
|
-
seen: Set<any>,
|
|
4
|
-
location: (string | number)[]
|
|
5
|
-
):
|
|
1
|
+
type Result =
|
|
6
2
|
| { serializable: true }
|
|
7
3
|
| {
|
|
8
4
|
serializable: false;
|
|
9
5
|
location: (string | number)[];
|
|
10
6
|
reason: string;
|
|
11
|
-
}
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const checkSerializableWithoutCircularReference = (
|
|
10
|
+
o: { [key: string]: any },
|
|
11
|
+
seen: Set<any>,
|
|
12
|
+
location: (string | number)[]
|
|
13
|
+
): Result => {
|
|
12
14
|
if (
|
|
13
15
|
o === undefined ||
|
|
14
16
|
o === null ||
|
|
@@ -25,7 +27,7 @@ const checkSerializableWithoutCircularReference = (
|
|
|
25
27
|
) {
|
|
26
28
|
return {
|
|
27
29
|
serializable: false,
|
|
28
|
-
location,
|
|
30
|
+
location: location.slice(),
|
|
29
31
|
reason: typeof o === 'function' ? 'Function' : String(o),
|
|
30
32
|
};
|
|
31
33
|
}
|
|
@@ -34,7 +36,7 @@ const checkSerializableWithoutCircularReference = (
|
|
|
34
36
|
return {
|
|
35
37
|
serializable: false,
|
|
36
38
|
reason: 'Circular reference',
|
|
37
|
-
location,
|
|
39
|
+
location: location.slice(),
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -42,30 +44,38 @@ const checkSerializableWithoutCircularReference = (
|
|
|
42
44
|
|
|
43
45
|
if (Array.isArray(o)) {
|
|
44
46
|
for (let i = 0; i < o.length; i++) {
|
|
47
|
+
location.push(i);
|
|
45
48
|
const childResult = checkSerializableWithoutCircularReference(
|
|
46
49
|
o[i],
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
seen,
|
|
51
|
+
location
|
|
49
52
|
);
|
|
53
|
+
location.pop();
|
|
50
54
|
|
|
51
55
|
if (!childResult.serializable) {
|
|
56
|
+
seen.delete(o);
|
|
52
57
|
return childResult;
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
} else {
|
|
56
61
|
for (const key in o) {
|
|
62
|
+
location.push(key);
|
|
57
63
|
const childResult = checkSerializableWithoutCircularReference(
|
|
58
64
|
o[key],
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
seen,
|
|
66
|
+
location
|
|
61
67
|
);
|
|
68
|
+
location.pop();
|
|
62
69
|
|
|
63
70
|
if (!childResult.serializable) {
|
|
71
|
+
seen.delete(o);
|
|
64
72
|
return childResult;
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
}
|
|
68
76
|
|
|
77
|
+
seen.delete(o);
|
|
78
|
+
|
|
69
79
|
return { serializable: true };
|
|
70
80
|
};
|
|
71
81
|
|
|
@@ -28,14 +28,30 @@ type NavigateAction<State extends NavigationState> = {
|
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
// Cache the normalized config across calls for the same `options` reference,
|
|
32
|
+
// so we don't re-walk the config tree on every action conversion.
|
|
33
|
+
const cachedNormalizedConfig = new WeakMap<Options, ConfigItem>();
|
|
34
|
+
|
|
31
35
|
export function getActionFromState(
|
|
32
36
|
state: PartialState<NavigationState>,
|
|
33
37
|
options?: Options
|
|
34
38
|
): NavigateAction<NavigationState> | CommonActions.Action | undefined {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
let normalizedConfig;
|
|
40
|
+
|
|
41
|
+
if (options) {
|
|
42
|
+
const cached = cachedNormalizedConfig.get(options);
|
|
43
|
+
|
|
44
|
+
if (cached) {
|
|
45
|
+
normalizedConfig = cached;
|
|
46
|
+
} else {
|
|
47
|
+
normalizedConfig = createNormalizedConfigItem(
|
|
48
|
+
options as PathConfig<object> | string
|
|
49
|
+
);
|
|
50
|
+
cachedNormalizedConfig.set(options, normalizedConfig as ConfigItem);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
normalizedConfig = {};
|
|
54
|
+
}
|
|
39
55
|
|
|
40
56
|
const routes =
|
|
41
57
|
state.index != null ? state.routes.slice(0, state.index + 1) : state.routes;
|
package/src/getStateFromPath.tsx
CHANGED
|
@@ -49,6 +49,7 @@ type ParsedRoute = {
|
|
|
49
49
|
type ConfigResources = {
|
|
50
50
|
initialRoutes: InitialRouteConfig[];
|
|
51
51
|
configs: RouteConfig[];
|
|
52
|
+
configsByScreen: Record<string, RouteConfig[]>;
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
/**
|
|
@@ -76,7 +77,8 @@ export function getStateFromPath<ParamList extends {}>(
|
|
|
76
77
|
path: string,
|
|
77
78
|
options?: Options<ParamList>
|
|
78
79
|
): ResultState | undefined {
|
|
79
|
-
const { initialRoutes, configs } =
|
|
80
|
+
const { initialRoutes, configs, configsByScreen } =
|
|
81
|
+
getConfigResources(options);
|
|
80
82
|
|
|
81
83
|
const screens = options?.screens;
|
|
82
84
|
|
|
@@ -142,7 +144,11 @@ export function getStateFromPath<ParamList extends {}>(
|
|
|
142
144
|
|
|
143
145
|
// We match the whole path against the regex instead of segments
|
|
144
146
|
// This makes sure matches such as wildcard will catch any unmatched routes, even if nested
|
|
145
|
-
const { routes, remainingPath } = matchAgainstConfigs(
|
|
147
|
+
const { routes, remainingPath } = matchAgainstConfigs(
|
|
148
|
+
remaining,
|
|
149
|
+
configs,
|
|
150
|
+
configsByScreen
|
|
151
|
+
);
|
|
146
152
|
|
|
147
153
|
if (routes !== undefined) {
|
|
148
154
|
// This will always be empty if full path matched
|
|
@@ -189,12 +195,16 @@ function prepareConfigResources(options?: Options<{}>) {
|
|
|
189
195
|
|
|
190
196
|
checkForDuplicatedConfigs(configs);
|
|
191
197
|
|
|
192
|
-
const
|
|
198
|
+
const configsByScreen: Record<string, RouteConfig[]> = {};
|
|
199
|
+
|
|
200
|
+
for (const c of configs) {
|
|
201
|
+
(configsByScreen[c.screen] ??= []).push(c);
|
|
202
|
+
}
|
|
193
203
|
|
|
194
204
|
return {
|
|
195
205
|
initialRoutes,
|
|
196
206
|
configs,
|
|
197
|
-
|
|
207
|
+
configsByScreen,
|
|
198
208
|
};
|
|
199
209
|
}
|
|
200
210
|
|
|
@@ -337,15 +347,11 @@ function checkForDuplicatedConfigs(configs: RouteConfig[]) {
|
|
|
337
347
|
}, {});
|
|
338
348
|
}
|
|
339
349
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}));
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
|
|
350
|
+
const matchAgainstConfigs = (
|
|
351
|
+
remaining: string,
|
|
352
|
+
configs: RouteConfig[],
|
|
353
|
+
configsByScreen: Record<string, RouteConfig[]>
|
|
354
|
+
) => {
|
|
349
355
|
let routes: ParsedRoute[] | undefined;
|
|
350
356
|
let remainingPath = remaining;
|
|
351
357
|
|
|
@@ -360,13 +366,10 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
|
|
|
360
366
|
// If our regex matches, we need to extract params from the path
|
|
361
367
|
if (match) {
|
|
362
368
|
routes = config.routeNames.map((routeName) => {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
arrayStartsWith(config.segments, c.segments)
|
|
368
|
-
);
|
|
369
|
-
});
|
|
369
|
+
// Check matching name AND pattern in case same screen is used at different levels in config
|
|
370
|
+
const routeConfig = configsByScreen[routeName]?.find((c) =>
|
|
371
|
+
arrayStartsWith(config.segments, c.segments)
|
|
372
|
+
);
|
|
370
373
|
|
|
371
374
|
const params =
|
|
372
375
|
routeConfig && match.groups
|
package/src/index.tsx
CHANGED
package/src/types.tsx
CHANGED
|
@@ -10,14 +10,148 @@ import type {
|
|
|
10
10
|
} from '@react-navigation/routers';
|
|
11
11
|
import type * as React from 'react';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Flatten a type to remove all type alias names, unions etc.
|
|
15
|
+
* This will show a plain object when hovering over the type.
|
|
16
|
+
*/
|
|
17
|
+
type FlatType<T> = { [K in keyof T]: T[K] } & {};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* keyof T doesn't work for union types. We can use distributive conditional types instead.
|
|
21
|
+
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
|
|
22
|
+
*/
|
|
23
|
+
type KeysOf<T> = T extends {} ? keyof T : never;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* We get a union type when using keyof, but we want an intersection instead.
|
|
27
|
+
* https://stackoverflow.com/a/50375286/1665026
|
|
28
|
+
*/
|
|
29
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
30
|
+
k: infer I
|
|
31
|
+
) => void
|
|
32
|
+
? I
|
|
33
|
+
: never;
|
|
34
|
+
|
|
35
|
+
type UnknownToUndefined<T> = unknown extends T ? undefined : T;
|
|
36
|
+
|
|
37
|
+
type ParamsForScreenComponent<T> = T extends {
|
|
38
|
+
screen: React.ComponentType<{ route: { params: infer P } }>;
|
|
39
|
+
}
|
|
40
|
+
? P
|
|
41
|
+
: T extends React.ComponentType<{ route: { params: infer P } }>
|
|
42
|
+
? P
|
|
43
|
+
: undefined;
|
|
44
|
+
|
|
45
|
+
type StaticNavigationConfig = {
|
|
46
|
+
readonly config: {
|
|
47
|
+
readonly screens?: Record<string, any>;
|
|
48
|
+
readonly groups?: {
|
|
49
|
+
[key: string]: {
|
|
50
|
+
screens: Record<string, any>;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
type ParamsForScreen<T> = T extends {
|
|
57
|
+
screen: infer Screen;
|
|
58
|
+
}
|
|
59
|
+
? Screen extends StaticNavigationConfig
|
|
60
|
+
? NavigatorScreenParams<StaticParamList<Screen>> | undefined
|
|
61
|
+
: UnknownToUndefined<ParamsForScreenComponent<T>>
|
|
62
|
+
: T extends StaticNavigationConfig
|
|
63
|
+
? NavigatorScreenParams<StaticParamList<T>> | undefined
|
|
64
|
+
: UnknownToUndefined<ParamsForScreenComponent<T>>;
|
|
65
|
+
|
|
66
|
+
type ParamListForScreens<Screens> = {
|
|
67
|
+
[Key in KeysOf<Screens>]: ParamsForScreen<Screens[Key]>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
type ParamListForGroups<
|
|
71
|
+
Groups extends
|
|
72
|
+
| Readonly<{
|
|
73
|
+
[key: string]: {
|
|
74
|
+
screens: Record<string, any>;
|
|
75
|
+
};
|
|
76
|
+
}>
|
|
77
|
+
| undefined,
|
|
78
|
+
> = Groups extends {
|
|
79
|
+
[key: string]: {
|
|
80
|
+
screens: Record<string, any>;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
? ParamListForScreens<UnionToIntersection<Groups[keyof Groups]['screens']>>
|
|
84
|
+
: {};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Infer the param list from the static navigation config.
|
|
88
|
+
*/
|
|
89
|
+
export type StaticParamList<T extends StaticNavigationConfig> = FlatType<
|
|
90
|
+
ParamListForScreens<T['config']['screens']> &
|
|
91
|
+
ParamListForGroups<T['config']['groups']>
|
|
92
|
+
>;
|
|
93
|
+
|
|
94
|
+
type ParamListForStaticNavigator<T> = T extends StaticNavigationConfig
|
|
95
|
+
? StaticParamList<T>
|
|
96
|
+
: {};
|
|
97
|
+
|
|
98
|
+
type ParamListForTypedNavigator<T> = T extends {
|
|
99
|
+
Screen: any;
|
|
100
|
+
} & PrivateValueStore<infer Value>
|
|
101
|
+
? Value[0]
|
|
102
|
+
: {};
|
|
103
|
+
|
|
104
|
+
type ParamListForRootNavigator<T> =
|
|
105
|
+
string extends keyof ParamListForTypedNavigator<T>
|
|
106
|
+
? ParamListForStaticNavigator<T>
|
|
107
|
+
: ParamListForTypedNavigator<T>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Root navigator used in the app.
|
|
111
|
+
* It's used for the global types in the app.
|
|
112
|
+
*
|
|
113
|
+
* Users need to use module augmentation to add their navigator type:
|
|
114
|
+
*
|
|
115
|
+
* ```ts
|
|
116
|
+
* // Navigator created with static or dynamic API
|
|
117
|
+
* const RootStack = createStackNavigator({
|
|
118
|
+
* // ...
|
|
119
|
+
* });
|
|
120
|
+
*
|
|
121
|
+
* type RootStackType = typeof RootStack;
|
|
122
|
+
*
|
|
123
|
+
* declare module '@react-navigation/core' {
|
|
124
|
+
* interface RootNavigator extends RootStackType {}
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
129
|
+
export interface RootNavigator {}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Theme object for the navigation components.
|
|
133
|
+
*
|
|
134
|
+
* Custom properties can be added using declaration merging:
|
|
135
|
+
*
|
|
136
|
+
* ```ts
|
|
137
|
+
* declare module '@react-navigation/core' {
|
|
138
|
+
* interface Theme extends NativeTheme {
|
|
139
|
+
* myCustomProperty: string;
|
|
140
|
+
* }
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
145
|
+
export interface Theme {}
|
|
146
|
+
|
|
147
|
+
type RootTheme = Theme;
|
|
148
|
+
|
|
13
149
|
declare global {
|
|
14
150
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
15
151
|
namespace ReactNavigation {
|
|
16
|
-
|
|
17
|
-
interface RootParamList {}
|
|
152
|
+
interface RootParamList extends ParamListForRootNavigator<RootNavigator> {}
|
|
18
153
|
|
|
19
|
-
|
|
20
|
-
interface Theme {}
|
|
154
|
+
interface Theme extends RootTheme {}
|
|
21
155
|
}
|
|
22
156
|
}
|
|
23
157
|
|
package/src/useEventEmitter.tsx
CHANGED
|
@@ -75,59 +75,54 @@ export function useEventEmitter<T extends Record<string, any>>(
|
|
|
75
75
|
target?: string;
|
|
76
76
|
canPreventDefault?: boolean;
|
|
77
77
|
}) => {
|
|
78
|
-
const items = listeners.current[type]
|
|
78
|
+
const items = listeners.current[type];
|
|
79
79
|
|
|
80
80
|
// Copy the current list of callbacks in case they are mutated during execution
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
81
|
+
let callbacks: Listeners | undefined;
|
|
82
|
+
|
|
83
|
+
if (items !== undefined) {
|
|
84
|
+
callbacks =
|
|
85
|
+
target !== undefined
|
|
86
|
+
? items[target]?.slice()
|
|
87
|
+
: ([] as Listeners)
|
|
88
|
+
.concat(...Object.keys(items).map((t) => items[t]))
|
|
89
|
+
.filter((cb, i, self) => self.lastIndexOf(cb) === i);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const descriptors: PropertyDescriptorMap = {
|
|
93
|
+
type: { enumerable: true, value: type },
|
|
92
94
|
};
|
|
93
95
|
|
|
94
96
|
if (target !== undefined) {
|
|
95
|
-
|
|
96
|
-
enumerable: true,
|
|
97
|
-
get() {
|
|
98
|
-
return target;
|
|
99
|
-
},
|
|
100
|
-
});
|
|
97
|
+
descriptors.target = { enumerable: true, value: target };
|
|
101
98
|
}
|
|
102
99
|
|
|
103
100
|
if (data !== undefined) {
|
|
104
|
-
|
|
105
|
-
enumerable: true,
|
|
106
|
-
get() {
|
|
107
|
-
return data;
|
|
108
|
-
},
|
|
109
|
-
});
|
|
101
|
+
descriptors.data = { enumerable: true, value: data };
|
|
110
102
|
}
|
|
111
103
|
|
|
104
|
+
let defaultPrevented = false;
|
|
105
|
+
|
|
112
106
|
if (canPreventDefault) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
enumerable: true,
|
|
118
|
-
get() {
|
|
119
|
-
return defaultPrevented;
|
|
120
|
-
},
|
|
107
|
+
descriptors.defaultPrevented = {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
get() {
|
|
110
|
+
return defaultPrevented;
|
|
121
111
|
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
112
|
+
};
|
|
113
|
+
descriptors.preventDefault = {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
value() {
|
|
116
|
+
defaultPrevented = true;
|
|
127
117
|
},
|
|
128
|
-
}
|
|
118
|
+
};
|
|
129
119
|
}
|
|
130
120
|
|
|
121
|
+
const event: EventArg<any, any, any> = Object.defineProperties(
|
|
122
|
+
{} as EventArg<any, any, any>,
|
|
123
|
+
descriptors
|
|
124
|
+
);
|
|
125
|
+
|
|
131
126
|
listenRef.current?.(event);
|
|
132
127
|
|
|
133
128
|
callbacks?.forEach((cb) => cb(event));
|