@react-navigation/core 7.14.0 → 8.0.0-alpha.1
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/BaseNavigationContainer.js +4 -9
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +12 -7
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +49 -0
- package/lib/module/NavigationProvider.js.map +1 -0
- package/lib/module/PreventRemoveProvider.js +1 -1
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +32 -21
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/createNavigationContainerRef.js.map +1 -1
- package/lib/module/getActionFromState.js +3 -2
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +1 -1
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getStateFromPath.js +3 -3
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js +1 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/theming/ThemeContext.js.map +1 -1
- package/lib/module/theming/ThemeProvider.js.map +1 -1
- package/lib/module/theming/useTheme.js +1 -1
- package/lib/module/theming/useTheme.js.map +1 -1
- package/lib/module/types.js +41 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useChildListeners.js +2 -4
- package/lib/module/useChildListeners.js.map +1 -1
- package/lib/module/useDescriptors.js +5 -9
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +9 -20
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEvents.js +1 -1
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useNavigation.js +31 -8
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +10 -12
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +18 -11
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +2 -14
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationState.js +42 -9
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +2 -7
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +1 -1
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +1 -1
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useRoute.js +23 -5
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +1 -2
- package/lib/module/useScheduleUpdate.js.map +1 -1
- package/lib/module/useSyncState.js +25 -9
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/module/utilities.js +2 -0
- package/lib/module/utilities.js.map +1 -0
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/NavigationProvider.d.ts +44 -0
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -0
- package/lib/typescript/src/SceneView.d.ts +1 -1
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +231 -80
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts +2 -2
- package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +2 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +188 -133
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +27 -109
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useNavigation.d.ts +7 -5
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +25 -114
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +8 -22
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts +2 -2
- package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +3 -11
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +10 -3
- package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useRoute.d.ts +8 -2
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +12 -3
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
- package/lib/typescript/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +99 -0
- package/lib/typescript/src/utilities.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/BaseNavigationContainer.tsx +3 -9
- package/src/NavigationIndependentTree.tsx +17 -9
- package/src/NavigationProvider.tsx +64 -0
- package/src/PreventRemoveProvider.tsx +1 -1
- package/src/SceneView.tsx +1 -7
- package/src/StaticNavigation.tsx +372 -134
- package/src/createNavigationContainerRef.tsx +2 -1
- package/src/getActionFromState.tsx +4 -2
- package/src/getPathFromState.tsx +6 -5
- package/src/getStateFromPath.tsx +11 -11
- package/src/index.tsx +8 -4
- package/src/theming/ThemeContext.tsx +3 -3
- package/src/theming/ThemeProvider.tsx +2 -1
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +392 -243
- package/src/useChildListeners.tsx +3 -2
- package/src/useDescriptors.tsx +11 -17
- package/src/useEventEmitter.tsx +14 -31
- package/src/useFocusEvents.tsx +1 -1
- package/src/useNavigation.tsx +57 -14
- package/src/useNavigationBuilder.tsx +10 -13
- package/src/useNavigationCache.tsx +40 -18
- package/src/useNavigationContainerRef.tsx +2 -2
- package/src/useNavigationHelpers.tsx +2 -19
- package/src/useNavigationState.tsx +90 -19
- package/src/useOnAction.tsx +1 -12
- package/src/useOnGetState.tsx +1 -1
- package/src/useOnPreventRemove.tsx +1 -1
- package/src/useRoute.tsx +52 -7
- package/src/useScheduleUpdate.tsx +1 -2
- package/src/useSyncState.tsx +28 -13
- package/src/utilities.tsx +122 -0
- package/lib/module/DeprecatedNavigationInChildContext.js +0 -9
- package/lib/module/DeprecatedNavigationInChildContext.js.map +0 -1
- package/lib/module/NavigationContext.js +0 -8
- package/lib/module/NavigationContext.js.map +0 -1
- package/lib/module/NavigationRouteContext.js +0 -9
- package/lib/module/NavigationRouteContext.js.map +0 -1
- package/lib/module/useClientLayoutEffect.js +0 -9
- package/lib/module/useClientLayoutEffect.js.map +0 -1
- package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts +0 -6
- package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationContext.d.ts +0 -8
- package/lib/typescript/src/NavigationContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationRouteContext.d.ts +0 -7
- package/lib/typescript/src/NavigationRouteContext.d.ts.map +0 -1
- package/lib/typescript/src/useClientLayoutEffect.d.ts +0 -6
- package/lib/typescript/src/useClientLayoutEffect.d.ts.map +0 -1
- package/src/DeprecatedNavigationInChildContext.tsx +0 -6
- package/src/NavigationContext.tsx +0 -11
- package/src/NavigationRouteContext.tsx +0 -9
- package/src/useClientLayoutEffect.tsx +0 -10
|
@@ -3,31 +3,106 @@ import * as React from 'react';
|
|
|
3
3
|
import useLatestCallback from 'use-latest-callback';
|
|
4
4
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
5
5
|
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import type {
|
|
7
|
+
NavigationListForNested,
|
|
8
|
+
NavigationProp,
|
|
9
|
+
RootNavigator,
|
|
10
|
+
} from './types';
|
|
11
|
+
import { useNavigation } from './useNavigation';
|
|
12
|
+
|
|
13
|
+
type NavigationStateListener = {
|
|
14
|
+
getState: () => NavigationState<ParamListBase>;
|
|
15
|
+
subscribe: (callback: () => void) => () => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type NavigationStateForNested<
|
|
19
|
+
Navigator,
|
|
20
|
+
RouteName extends keyof NavigationListForNested<Navigator>,
|
|
21
|
+
> = NavigationListForNested<Navigator>[RouteName] extends {
|
|
22
|
+
getState: () => infer State;
|
|
23
|
+
}
|
|
24
|
+
? State
|
|
25
|
+
: never;
|
|
9
26
|
|
|
10
27
|
/**
|
|
11
28
|
* Hook to get a value from the current navigation state using a selector.
|
|
12
29
|
*
|
|
13
|
-
*
|
|
30
|
+
* If the route name of the current or one of the parents is specified,
|
|
31
|
+
* the navigation state of the navigator for that route is used.
|
|
32
|
+
*
|
|
33
|
+
* A selector function must be provided to select the desired value from the navigation state.
|
|
14
34
|
*/
|
|
15
|
-
export function useNavigationState<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
35
|
+
export function useNavigationState<
|
|
36
|
+
const T,
|
|
37
|
+
const Navigator = RootNavigator,
|
|
38
|
+
const RouteName extends
|
|
39
|
+
keyof NavigationListForNested<Navigator> = keyof NavigationListForNested<Navigator>,
|
|
40
|
+
>(
|
|
41
|
+
routeName: RouteName,
|
|
42
|
+
selector: (state: NavigationStateForNested<Navigator, RouteName>) => T
|
|
43
|
+
): T;
|
|
44
|
+
export function useNavigationState<T>(
|
|
45
|
+
selector: (state: NavigationState<ParamListBase>) => T
|
|
46
|
+
): T;
|
|
47
|
+
export function useNavigationState(...args: unknown[]): unknown {
|
|
48
|
+
let navigation: NavigationProp<ParamListBase> | undefined,
|
|
49
|
+
stateListener: NavigationStateListener | undefined,
|
|
50
|
+
selector;
|
|
51
|
+
|
|
52
|
+
if (typeof args[0] === 'string') {
|
|
53
|
+
// `useNavigation` uses `use` internally, so it's fine to call it conditionally
|
|
54
|
+
// @ts-expect-error we can't specify the type here
|
|
55
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
56
|
+
navigation = useNavigation(args[0]);
|
|
57
|
+
selector = args[1];
|
|
58
|
+
} else {
|
|
59
|
+
selector = args[0];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (navigation == null) {
|
|
63
|
+
stateListener = React.use(NavigationStateListenerContext);
|
|
64
|
+
|
|
65
|
+
if (stateListener == null) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
"Couldn't get the navigation state. Is your component inside a navigator?"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const subscribe = React.useCallback(
|
|
73
|
+
(callback: () => void) => {
|
|
74
|
+
if (navigation) {
|
|
75
|
+
return navigation.addListener('state', callback);
|
|
76
|
+
} else if (stateListener) {
|
|
77
|
+
return stateListener.subscribe(callback);
|
|
78
|
+
} else {
|
|
79
|
+
throw new Error(
|
|
80
|
+
"Couldn't subscribe to navigation state changes. This is not expected."
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
[navigation, stateListener]
|
|
85
|
+
);
|
|
19
86
|
|
|
20
|
-
|
|
87
|
+
const getSnapshot = navigation
|
|
88
|
+
? navigation.getState
|
|
89
|
+
: stateListener?.getState;
|
|
90
|
+
|
|
91
|
+
if (getSnapshot == null) {
|
|
92
|
+
throw new Error("Couldn't get the navigation state. This is not expected.");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (typeof selector !== 'function') {
|
|
21
96
|
throw new Error(
|
|
22
|
-
|
|
97
|
+
`A selector function must be provided (got ${typeof selector}).`
|
|
23
98
|
);
|
|
24
99
|
}
|
|
25
100
|
|
|
26
101
|
const value = useSyncExternalStoreWithSelector(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
102
|
+
subscribe,
|
|
103
|
+
getSnapshot,
|
|
104
|
+
getSnapshot,
|
|
105
|
+
// @ts-expect-error we can't infer the type here
|
|
31
106
|
selector
|
|
32
107
|
);
|
|
33
108
|
|
|
@@ -73,9 +148,5 @@ export function NavigationStateListenerProvider({
|
|
|
73
148
|
}
|
|
74
149
|
|
|
75
150
|
const NavigationStateListenerContext = React.createContext<
|
|
76
|
-
|
|
|
77
|
-
getState: () => NavigationState<ParamListBase>;
|
|
78
|
-
subscribe: (callback: () => void) => () => void;
|
|
79
|
-
}
|
|
80
|
-
| undefined
|
|
151
|
+
NavigationStateListener | undefined
|
|
81
152
|
>(undefined);
|
package/src/useOnAction.tsx
CHANGED
|
@@ -7,7 +7,6 @@ import type {
|
|
|
7
7
|
} from '@react-navigation/routers';
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
|
|
10
|
-
import { DeprecatedNavigationInChildContext } from './DeprecatedNavigationInChildContext';
|
|
11
10
|
import {
|
|
12
11
|
type ChildActionListener,
|
|
13
12
|
type ChildBeforeRemoveListener,
|
|
@@ -53,9 +52,6 @@ export function useOnAction({
|
|
|
53
52
|
addListener: addListenerParent,
|
|
54
53
|
onDispatchAction,
|
|
55
54
|
} = React.useContext(NavigationBuilderContext);
|
|
56
|
-
const navigationInChildEnabled = React.useContext(
|
|
57
|
-
DeprecatedNavigationInChildContext
|
|
58
|
-
);
|
|
59
55
|
|
|
60
56
|
const routerConfigOptionsRef =
|
|
61
57
|
React.useRef<RouterConfigOptions>(routerConfigOptions);
|
|
@@ -131,14 +127,8 @@ export function useOnAction({
|
|
|
131
127
|
}
|
|
132
128
|
}
|
|
133
129
|
|
|
134
|
-
if (
|
|
135
|
-
typeof action.target === 'string' ||
|
|
136
|
-
// For backward compatibility
|
|
137
|
-
action.type === 'NAVIGATE_DEPRECATED' ||
|
|
138
|
-
navigationInChildEnabled
|
|
139
|
-
) {
|
|
130
|
+
if (typeof action.target === 'string') {
|
|
140
131
|
// If the action wasn't handled by current navigator or a parent navigator, let children handle it
|
|
141
|
-
// Handling this when target isn't specified is deprecated and will be removed in the future
|
|
142
132
|
for (let i = actionListeners.length - 1; i >= 0; i--) {
|
|
143
133
|
const listener = actionListeners[i];
|
|
144
134
|
|
|
@@ -155,7 +145,6 @@ export function useOnAction({
|
|
|
155
145
|
beforeRemoveListeners,
|
|
156
146
|
emitter,
|
|
157
147
|
getState,
|
|
158
|
-
navigationInChildEnabled,
|
|
159
148
|
key,
|
|
160
149
|
onActionParent,
|
|
161
150
|
onDispatchAction,
|
package/src/useOnGetState.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type GetStateListener,
|
|
7
7
|
NavigationBuilderContext,
|
|
8
8
|
} from './NavigationBuilderContext';
|
|
9
|
-
import { NavigationRouteContext } from './
|
|
9
|
+
import { NavigationRouteContext } from './NavigationProvider';
|
|
10
10
|
|
|
11
11
|
type Options = {
|
|
12
12
|
getState: () => NavigationState;
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type ChildBeforeRemoveListener,
|
|
9
9
|
NavigationBuilderContext,
|
|
10
10
|
} from './NavigationBuilderContext';
|
|
11
|
-
import { NavigationRouteContext } from './
|
|
11
|
+
import { NavigationRouteContext } from './NavigationProvider';
|
|
12
12
|
import type { EventMapCore } from './types';
|
|
13
13
|
import type { NavigationEventEmitter } from './useEventEmitter';
|
|
14
14
|
|
package/src/useRoute.tsx
CHANGED
|
@@ -1,22 +1,67 @@
|
|
|
1
1
|
import type { ParamListBase } from '@react-navigation/routers';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
NamedRouteContextListContext,
|
|
6
|
+
NavigationRouteContext,
|
|
7
|
+
} from './NavigationProvider';
|
|
8
|
+
import type { RootParamList, RouteForName, RouteProp } from './types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get all possible route names from a param list and its nested navigators.
|
|
12
|
+
*/
|
|
13
|
+
type AllRouteNames<ParamList extends {}> = RouteForName<
|
|
14
|
+
ParamList,
|
|
15
|
+
string
|
|
16
|
+
>['name'];
|
|
6
17
|
|
|
7
18
|
/**
|
|
8
19
|
* Hook to access the route prop of the parent screen anywhere.
|
|
9
20
|
*
|
|
10
21
|
* @returns Route prop of the parent screen.
|
|
11
22
|
*/
|
|
12
|
-
export function useRoute<
|
|
13
|
-
const
|
|
23
|
+
export function useRoute<
|
|
24
|
+
const ParamList extends {} = RootParamList,
|
|
25
|
+
const RouteName extends AllRouteNames<ParamList> = AllRouteNames<ParamList>,
|
|
26
|
+
>(name: RouteName): RouteForName<ParamList, RouteName>;
|
|
27
|
+
export function useRoute<
|
|
28
|
+
const ParamList extends {} = RootParamList,
|
|
29
|
+
>(): {} extends ParamList
|
|
30
|
+
? RouteProp<ParamListBase>
|
|
31
|
+
: ParamList extends ParamListBase
|
|
32
|
+
? RouteForName<ParamList, string>
|
|
33
|
+
: RouteProp<ParamListBase>;
|
|
34
|
+
|
|
35
|
+
export function useRoute(name?: string) {
|
|
36
|
+
if (name === undefined) {
|
|
37
|
+
const route = React.use(NavigationRouteContext);
|
|
38
|
+
|
|
39
|
+
if (route === undefined) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
"Couldn't find a route object. Is your component inside a screen in a navigator?"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return route;
|
|
46
|
+
}
|
|
14
47
|
|
|
15
|
-
|
|
48
|
+
const NamedRouteContextList = React.use(NamedRouteContextListContext);
|
|
49
|
+
|
|
50
|
+
if (NamedRouteContextList === undefined) {
|
|
16
51
|
throw new Error(
|
|
17
|
-
"Couldn't find a
|
|
52
|
+
"Couldn't find a parent screen. Is your component inside a screen in a navigator?"
|
|
18
53
|
);
|
|
19
54
|
}
|
|
20
55
|
|
|
21
|
-
|
|
56
|
+
const NamedRouteContext = NamedRouteContextList[name];
|
|
57
|
+
|
|
58
|
+
if (NamedRouteContext === undefined) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Couldn't find a route named '${name}' in any of the parent screens. Is your component inside the correct screen?`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const route = React.use(NamedRouteContext);
|
|
65
|
+
|
|
66
|
+
return route;
|
|
22
67
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
import { NavigationBuilderContext } from './NavigationBuilderContext';
|
|
4
|
-
import { useClientLayoutEffect } from './useClientLayoutEffect';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* When screen config changes, we want to update the navigator in the same update phase.
|
|
@@ -19,5 +18,5 @@ export function useScheduleUpdate(callback: () => void) {
|
|
|
19
18
|
// However, since we are using sync store, it might be fine
|
|
20
19
|
scheduleUpdate(callback);
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
React.useLayoutEffect(flushUpdates);
|
|
23
22
|
}
|
package/src/useSyncState.tsx
CHANGED
|
@@ -2,9 +2,10 @@ import * as React from 'react';
|
|
|
2
2
|
import useLatestCallback from 'use-latest-callback';
|
|
3
3
|
|
|
4
4
|
import { deepFreeze } from './deepFreeze';
|
|
5
|
+
import { useLazyValue } from './useLazyValue';
|
|
5
6
|
|
|
6
7
|
const createStore = <T,>(getInitialState: () => T) => {
|
|
7
|
-
const listeners
|
|
8
|
+
const listeners = new Set<() => void>();
|
|
8
9
|
|
|
9
10
|
let initialized = false;
|
|
10
11
|
let state: T;
|
|
@@ -33,14 +34,10 @@ const createStore = <T,>(getInitialState: () => T) => {
|
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
const subscribe = (callback: () => void) => {
|
|
36
|
-
listeners.
|
|
37
|
+
listeners.add(callback);
|
|
37
38
|
|
|
38
39
|
return () => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (index > -1) {
|
|
42
|
-
listeners.splice(index, 1);
|
|
43
|
-
}
|
|
40
|
+
listeners.delete(callback);
|
|
44
41
|
};
|
|
45
42
|
};
|
|
46
43
|
|
|
@@ -64,15 +61,31 @@ const createStore = <T,>(getInitialState: () => T) => {
|
|
|
64
61
|
};
|
|
65
62
|
|
|
66
63
|
export function useSyncState<T>(getInitialState: () => T) {
|
|
67
|
-
const store =
|
|
64
|
+
const store = useLazyValue(() => createStore(getInitialState));
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
store.getState,
|
|
72
|
-
|
|
66
|
+
// Use a reducer with `store.getState` to always have the latest state
|
|
67
|
+
const [state, rerender] = React.useReducer(
|
|
68
|
+
(_) => store.getState(),
|
|
69
|
+
undefined,
|
|
70
|
+
() => store.getState()
|
|
73
71
|
);
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
// Instead of subscribing with `useSyncExternalStore`,
|
|
74
|
+
// we add custom subscription logic in an effect.
|
|
75
|
+
// This means React isn't forced to re-render immediately
|
|
76
|
+
// and state updates work with `useTransition`.
|
|
77
|
+
// The disadvantage is that it can potentially cause tearing.
|
|
78
|
+
// However, since we subscribe to the store only once,
|
|
79
|
+
// and pass this value down, it should not happen in practice.
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
const unsubscribe = store.subscribe(() => rerender());
|
|
82
|
+
|
|
83
|
+
// We need to rerender again after the effect runs
|
|
84
|
+
// So we handle store changes after render and before the effect
|
|
85
|
+
rerender();
|
|
86
|
+
|
|
87
|
+
return unsubscribe;
|
|
88
|
+
}, [store]);
|
|
76
89
|
|
|
77
90
|
const pendingUpdatesRef = React.useRef<(() => void)[]>([]);
|
|
78
91
|
|
|
@@ -95,6 +108,8 @@ export function useSyncState<T>(getInitialState: () => T) {
|
|
|
95
108
|
}
|
|
96
109
|
});
|
|
97
110
|
|
|
111
|
+
React.useEffect(flushUpdates);
|
|
112
|
+
|
|
98
113
|
return {
|
|
99
114
|
state,
|
|
100
115
|
getState: store.getState,
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flatten a type to remove all type alias names, unions etc.
|
|
3
|
+
* This will show a plain object when hovering over the type.
|
|
4
|
+
*/
|
|
5
|
+
export type FlatType<T> = { [K in keyof T]: T[K] } & {};
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* keyof T doesn't work for union types. We can use distributive conditional types instead.
|
|
9
|
+
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
|
|
10
|
+
*/
|
|
11
|
+
export type KeysOf<T> = T extends {} ? keyof T : never;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extract string keys from an object type.
|
|
15
|
+
*/
|
|
16
|
+
export type KeyOf<T extends {}> = Extract<keyof T, string>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* We get a union type when using keyof, but we want an intersection instead.
|
|
20
|
+
* https://stackoverflow.com/a/50375286/1665026
|
|
21
|
+
*/
|
|
22
|
+
export type UnionToIntersection<U> = (
|
|
23
|
+
U extends any ? (k: U) => void : never
|
|
24
|
+
) extends (k: infer I) => void
|
|
25
|
+
? I
|
|
26
|
+
: never;
|
|
27
|
+
|
|
28
|
+
export type UnknownToUndefined<T> = unknown extends T ? undefined : T;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Exclude undefined from a type.
|
|
32
|
+
* Similar to NonNullable but only excludes undefined, not null.
|
|
33
|
+
*/
|
|
34
|
+
export type NotUndefined<T> = T extends undefined ? never : T;
|
|
35
|
+
|
|
36
|
+
export type AnyToUnknown<T> = 0 extends 1 & T ? unknown : T;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Check if a function type has arguments.
|
|
40
|
+
*/
|
|
41
|
+
export type HasArguments<T extends (...args: any[]) => any> =
|
|
42
|
+
Parameters<T> extends []
|
|
43
|
+
? false
|
|
44
|
+
: Parameters<T> extends [undefined?]
|
|
45
|
+
? false
|
|
46
|
+
: true;
|
|
47
|
+
|
|
48
|
+
export type ValidPathPattern = `:${string}` | `${string}/:${string}`;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Strip regex pattern from a path param.
|
|
52
|
+
* e.g. `userId([a-z]+)` -> `userId`
|
|
53
|
+
*/
|
|
54
|
+
type StripRegex<Param extends string> = Param extends `${infer Name}(${string})`
|
|
55
|
+
? Name
|
|
56
|
+
: Param;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Extract a single path param from a segment.
|
|
60
|
+
* e.g. `:userId` -> `{ userId: string }`, `:id?` -> `{ id?: string }`
|
|
61
|
+
*/
|
|
62
|
+
type ExtractSegmentParam<Segment extends string> =
|
|
63
|
+
Segment extends `:${infer Param}?`
|
|
64
|
+
? { [K in StripRegex<Param>]?: string }
|
|
65
|
+
: Segment extends `:${infer Param}`
|
|
66
|
+
? { [K in StripRegex<Param>]: string }
|
|
67
|
+
: {};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Extract path params from a path string.
|
|
71
|
+
* e.g. `/foo/:userId/:postId` -> `{ userId: string; postId: string }`
|
|
72
|
+
* Supports optional params with `?` suffix.
|
|
73
|
+
* Params must start with `:` at the beginning of a segment (after `/`).
|
|
74
|
+
*/
|
|
75
|
+
export type ExtractParamStrings<Path extends string> =
|
|
76
|
+
Path extends `${infer Segment}/${infer Rest}`
|
|
77
|
+
? ExtractSegmentParam<Segment> & ExtractParamStrings<Rest>
|
|
78
|
+
: ExtractSegmentParam<Path>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Extract the parsed params type from base params and parse functions.
|
|
82
|
+
* Applies the return type of parse functions to the corresponding params.
|
|
83
|
+
*/
|
|
84
|
+
export type ExtractParamsType<Params, Parse> = {
|
|
85
|
+
[K in keyof Params]: K extends keyof Parse
|
|
86
|
+
? Parse[K] extends (value: string) => infer R
|
|
87
|
+
? R
|
|
88
|
+
: Params[K]
|
|
89
|
+
: Params[K];
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Infer the path string from a linking config.
|
|
94
|
+
*/
|
|
95
|
+
export type InferPath<T> = T extends { path: infer P extends string }
|
|
96
|
+
? P
|
|
97
|
+
: never;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Infer the parse functions from a linking config.
|
|
101
|
+
*/
|
|
102
|
+
export type InferParse<T> = T extends { parse: infer P } ? P : {};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Infer the params type from a screen component or nested navigator.
|
|
106
|
+
*/
|
|
107
|
+
export type InferScreenParams<T> =
|
|
108
|
+
T extends React.ComponentType<{ route: { params: infer P } }>
|
|
109
|
+
? P
|
|
110
|
+
: T extends { config: { screens: infer Screens } }
|
|
111
|
+
? import('./types').NavigatorScreenParams<{
|
|
112
|
+
[K in keyof Screens]: Screens[K] extends React.ComponentType<{
|
|
113
|
+
route: { params: infer P };
|
|
114
|
+
}>
|
|
115
|
+
? P
|
|
116
|
+
: Screens[K] extends { screen: infer S }
|
|
117
|
+
? S extends React.ComponentType<{ route: { params: infer P } }>
|
|
118
|
+
? P
|
|
119
|
+
: undefined
|
|
120
|
+
: undefined;
|
|
121
|
+
}>
|
|
122
|
+
: undefined;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Context which enables deprecated bubbling to child navigators.
|
|
7
|
-
*/
|
|
8
|
-
export const DeprecatedNavigationInChildContext = /*#__PURE__*/React.createContext(false);
|
|
9
|
-
//# sourceMappingURL=DeprecatedNavigationInChildContext.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","DeprecatedNavigationInChildContext","createContext"],"sourceRoot":"../../src","sources":["DeprecatedNavigationInChildContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,kCAAkC,gBAAGD,KAAK,CAACE,aAAa,CAAC,KAAK,CAAC","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","NavigationContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAI9B;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,gBAAGD,KAAK,CAACE,aAAa,CAElDC,SAAS,CAAC","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","NavigationRouteContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationRouteContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,gBAAGD,KAAK,CAACE,aAAa,CAEvDC,SAAS,CAAC","ignoreList":[]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Use `useEffect` during SSR and `useLayoutEffect` in the Browser & React Native to avoid warnings.
|
|
7
|
-
*/
|
|
8
|
-
export const useClientLayoutEffect = typeof document !== 'undefined' || typeof navigator !== 'undefined' && navigator.product === 'ReactNative' ? React.useLayoutEffect : React.useEffect;
|
|
9
|
-
//# sourceMappingURL=useClientLayoutEffect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","useClientLayoutEffect","document","navigator","product","useLayoutEffect","useEffect"],"sourceRoot":"../../src","sources":["useClientLayoutEffect.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,qBAAqB,GAChC,OAAOC,QAAQ,KAAK,WAAW,IAC9B,OAAOC,SAAS,KAAK,WAAW,IAAIA,SAAS,CAACC,OAAO,KAAK,aAAc,GACrEJ,KAAK,CAACK,eAAe,GACrBL,KAAK,CAACM,SAAS","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DeprecatedNavigationInChildContext.d.ts","sourceRoot":"","sources":["../../../src/DeprecatedNavigationInChildContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,kCAAkC,wBAA6B,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ParamListBase } from '@react-navigation/routers';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import type { NavigationProp } from './types';
|
|
4
|
-
/**
|
|
5
|
-
* Context which holds the navigation prop for a screen.
|
|
6
|
-
*/
|
|
7
|
-
export declare const NavigationContext: React.Context<NavigationProp<ParamListBase> | undefined>;
|
|
8
|
-
//# sourceMappingURL=NavigationContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationContext.d.ts","sourceRoot":"","sources":["../../../src/NavigationContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,iBAAiB,0DAElB,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Route } from '@react-navigation/routers';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
/**
|
|
4
|
-
* Context which holds the route prop for a screen.
|
|
5
|
-
*/
|
|
6
|
-
export declare const NavigationRouteContext: React.Context<Route<string> | undefined>;
|
|
7
|
-
//# sourceMappingURL=NavigationRouteContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationRouteContext.d.ts","sourceRoot":"","sources":["../../../src/NavigationRouteContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,sBAAsB,0CAEvB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useClientLayoutEffect.d.ts","sourceRoot":"","sources":["../../../src/useClientLayoutEffect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,qBAAqB,wBAIb,CAAC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ParamListBase } from '@react-navigation/routers';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
import type { NavigationProp } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Context which holds the navigation prop for a screen.
|
|
8
|
-
*/
|
|
9
|
-
export const NavigationContext = React.createContext<
|
|
10
|
-
NavigationProp<ParamListBase> | undefined
|
|
11
|
-
>(undefined);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Use `useEffect` during SSR and `useLayoutEffect` in the Browser & React Native to avoid warnings.
|
|
5
|
-
*/
|
|
6
|
-
export const useClientLayoutEffect =
|
|
7
|
-
typeof document !== 'undefined' ||
|
|
8
|
-
(typeof navigator !== 'undefined' && navigator.product === 'ReactNative')
|
|
9
|
-
? React.useLayoutEffect
|
|
10
|
-
: React.useEffect;
|