@amazon-devices/react-navigation__native 7.0.1759135970 → 8.0.9000000000
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/SystemBundles/0fc5c971c5cf41a0dab235bcc6d58e5c06d9aaff650fa9815b525f8b9bb70a03.bundle +9116 -0
- package/SystemBundles/0fc5c971c5cf41a0dab235bcc6d58e5c06d9aaff650fa9815b525f8b9bb70a03.map +3543 -0
- package/SystemModules/amzn__react-navigation__native-8.modules.txt +24 -0
- package/SystemModules/amzn__react-navigation__native-8.private.modules.txt +77 -0
- package/SystemModules/keplerscript-system-bundle-config.json +4 -4
- package/kepler-compatibility.json +2 -2
- package/lib/module/Link.js +31 -10
- package/lib/module/Link.js.map +1 -1
- package/lib/module/LinkingContext.js +7 -3
- package/lib/module/LinkingContext.js.map +1 -1
- package/lib/module/LocaleDirContext.js +6 -0
- package/lib/module/LocaleDirContext.js.map +1 -0
- package/lib/module/NavigationContainer.js +87 -59
- package/lib/module/NavigationContainer.js.map +1 -1
- package/lib/module/ServerContainer.js +20 -10
- package/lib/module/ServerContainer.js.map +1 -1
- package/lib/module/ServerContext.js +3 -2
- package/lib/module/ServerContext.js.map +1 -1
- package/lib/module/UnhandledLinkingContext.js +14 -0
- package/lib/module/UnhandledLinkingContext.js.map +1 -0
- package/lib/module/__stubs__/createStackNavigator.js +18 -0
- package/lib/module/__stubs__/createStackNavigator.js.map +1 -0
- package/lib/module/__stubs__/window.js +75 -0
- package/lib/module/__stubs__/window.js.map +1 -0
- package/lib/module/createMemoryHistory.js +19 -17
- package/lib/module/createMemoryHistory.js.map +1 -1
- package/lib/module/createStaticNavigation.js +54 -0
- package/lib/module/createStaticNavigation.js.map +1 -0
- package/lib/module/extractPathFromURL.js +6 -5
- package/lib/module/extractPathFromURL.js.map +1 -1
- package/lib/module/index.js +18 -13
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/module/theming/DarkTheme.js +6 -3
- package/lib/module/theming/DarkTheme.js.map +1 -1
- package/lib/module/theming/DefaultTheme.js +6 -3
- package/lib/module/theming/DefaultTheme.js.map +1 -1
- package/lib/module/theming/fonts.js +61 -0
- package/lib/module/theming/fonts.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useBackButton.js +3 -1
- package/lib/module/useBackButton.js.map +1 -1
- package/lib/module/useBackButton.native.js +3 -1
- package/lib/module/useBackButton.native.js.map +1 -1
- package/lib/module/useDocumentTitle.js +6 -4
- package/lib/module/useDocumentTitle.js.map +1 -1
- package/lib/module/useDocumentTitle.native.js +4 -2
- package/lib/module/useDocumentTitle.native.js.map +1 -1
- package/lib/module/useLinkBuilder.js +71 -40
- package/lib/module/useLinkBuilder.js.map +1 -1
- package/lib/module/useLinkProps.js +41 -36
- package/lib/module/useLinkProps.js.map +1 -1
- package/lib/module/useLinkTo.js +18 -28
- package/lib/module/useLinkTo.js.map +1 -1
- package/lib/module/useLinking.js +47 -19
- package/lib/module/useLinking.js.map +1 -1
- package/lib/module/useLinking.native.js +33 -28
- package/lib/module/useLinking.native.js.map +1 -1
- package/lib/module/useLocale.js +18 -0
- package/lib/module/useLocale.js.map +1 -0
- package/lib/module/useRoutePath.js +30 -0
- package/lib/module/useRoutePath.js.map +1 -0
- package/lib/module/useScrollToTop.js +11 -7
- package/lib/module/useScrollToTop.js.map +1 -1
- package/lib/module/useThenable.js +4 -1
- package/lib/module/useThenable.js.map +1 -1
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/Link.d.ts +8 -10
- package/lib/typescript/src/Link.d.ts.map +1 -1
- package/lib/typescript/src/LinkingContext.d.ts +2 -3
- package/lib/typescript/src/LinkingContext.d.ts.map +1 -1
- package/lib/typescript/src/LocaleDirContext.d.ts +4 -0
- package/lib/typescript/src/LocaleDirContext.d.ts.map +1 -0
- package/lib/typescript/src/NavigationContainer.d.ts +36 -13
- package/lib/typescript/src/NavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/ServerContainer.d.ts +2 -3
- package/lib/typescript/src/ServerContainer.d.ts.map +1 -1
- package/lib/typescript/src/ServerContext.d.ts +1 -2
- package/lib/typescript/src/ServerContext.d.ts.map +1 -1
- package/lib/typescript/src/UnhandledLinkingContext.d.ts +6 -0
- package/lib/typescript/src/UnhandledLinkingContext.d.ts.map +1 -0
- package/lib/typescript/src/__stubs__/createStackNavigator.d.ts +13 -0
- package/lib/typescript/src/__stubs__/createStackNavigator.d.ts.map +1 -0
- package/lib/typescript/src/{__mocks__ → __stubs__}/window.d.ts +5 -6
- package/lib/typescript/src/__stubs__/window.d.ts.map +1 -0
- package/lib/typescript/src/createMemoryHistory.d.ts +1 -1
- package/lib/typescript/src/createMemoryHistory.d.ts.map +1 -1
- package/lib/typescript/src/createStaticNavigation.d.ts +34 -0
- package/lib/typescript/src/createStaticNavigation.d.ts.map +1 -0
- package/lib/typescript/src/extractPathFromURL.d.ts +1 -1
- package/lib/typescript/src/extractPathFromURL.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +15 -12
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/DarkTheme.d.ts +1 -2
- package/lib/typescript/src/theming/DarkTheme.d.ts.map +1 -1
- package/lib/typescript/src/theming/DefaultTheme.d.ts +1 -2
- package/lib/typescript/src/theming/DefaultTheme.d.ts.map +1 -1
- package/lib/typescript/src/theming/fonts.d.ts +53 -0
- package/lib/typescript/src/theming/fonts.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +35 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useBackButton.d.ts +1 -2
- package/lib/typescript/src/useBackButton.d.ts.map +1 -1
- package/lib/typescript/src/useBackButton.native.d.ts +1 -1
- package/lib/typescript/src/useBackButton.native.d.ts.map +1 -1
- package/lib/typescript/src/useDocumentTitle.d.ts +1 -1
- package/lib/typescript/src/useDocumentTitle.d.ts.map +1 -1
- package/lib/typescript/src/useDocumentTitle.native.d.ts +1 -1
- package/lib/typescript/src/useDocumentTitle.native.d.ts.map +1 -1
- package/lib/typescript/src/useLinkBuilder.d.ts +97 -3
- package/lib/typescript/src/useLinkBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useLinkProps.d.ts +23 -10
- package/lib/typescript/src/useLinkProps.d.ts.map +1 -1
- package/lib/typescript/src/useLinkTo.d.ts +6 -8
- package/lib/typescript/src/useLinkTo.d.ts.map +1 -1
- package/lib/typescript/src/useLinking.d.ts +5 -46
- package/lib/typescript/src/useLinking.d.ts.map +1 -1
- package/lib/typescript/src/useLinking.native.d.ts +11 -29
- package/lib/typescript/src/useLinking.native.d.ts.map +1 -1
- package/lib/typescript/src/useLocale.d.ts +7 -0
- package/lib/typescript/src/useLocale.d.ts.map +1 -0
- package/lib/typescript/src/useRoutePath.d.ts +7 -0
- package/lib/typescript/src/useRoutePath.d.ts.map +1 -0
- package/lib/typescript/src/useScrollToTop.d.ts +2 -2
- package/lib/typescript/src/useScrollToTop.d.ts.map +1 -1
- package/lib/typescript/src/useThenable.d.ts +1 -1
- package/lib/typescript/src/useThenable.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Link.tsx +36 -20
- package/src/LinkingContext.tsx +9 -5
- package/src/LocaleDirContext.tsx +7 -0
- package/src/NavigationContainer.tsx +128 -69
- package/src/ServerContainer.tsx +4 -3
- package/src/ServerContext.tsx +1 -3
- package/src/UnhandledLinkingContext.tsx +18 -0
- package/src/__stubs__/createStackNavigator.tsx +46 -0
- package/src/{__mocks__ → __stubs__}/window.tsx +8 -8
- package/src/createMemoryHistory.tsx +16 -11
- package/src/createStaticNavigation.tsx +109 -0
- package/src/extractPathFromURL.tsx +3 -3
- package/src/index.tsx +15 -12
- package/src/theming/DarkTheme.tsx +3 -3
- package/src/theming/DefaultTheme.tsx +3 -3
- package/src/theming/fonts.tsx +63 -0
- package/src/types.tsx +49 -3
- package/src/useBackButton.native.tsx +2 -2
- package/src/useBackButton.tsx +2 -2
- package/src/useDocumentTitle.native.tsx +2 -2
- package/src/useDocumentTitle.tsx +2 -2
- package/src/useLinkBuilder.tsx +100 -55
- package/src/useLinkProps.tsx +80 -50
- package/src/useLinkTo.tsx +13 -53
- package/src/useLinking.native.tsx +33 -31
- package/src/useLinking.tsx +70 -23
- package/src/useLocale.tsx +18 -0
- package/src/useRoutePath.tsx +34 -0
- package/src/useScrollToTop.tsx +16 -12
- package/src/useThenable.tsx +2 -1
- package/SystemBundles/8f36606502d3b658fa1ffc07fee4da0e39a8ce388742799c9ccdb66b39ef0362.bundle +0 -15196
- package/SystemBundles/8f36606502d3b658fa1ffc07fee4da0e39a8ce388742799c9ccdb66b39ef0362.map +0 -1
- package/SystemModules/amzn__react-navigation__native-7.modules.txt +0 -76
- package/SystemModules/amzn__react-navigation__native-7.private.modules.txt +0 -101
- package/THIRD_PARTY_NOTICES.txt +0 -24
- package/lib/commonjs/Link.js +0 -50
- package/lib/commonjs/Link.js.map +0 -1
- package/lib/commonjs/LinkingContext.js +0 -15
- package/lib/commonjs/LinkingContext.js.map +0 -1
- package/lib/commonjs/NavigationContainer.js +0 -109
- package/lib/commonjs/NavigationContainer.js.map +0 -1
- package/lib/commonjs/ServerContainer.js +0 -54
- package/lib/commonjs/ServerContainer.js.map +0 -1
- package/lib/commonjs/ServerContext.js +0 -12
- package/lib/commonjs/ServerContext.js.map +0 -1
- package/lib/commonjs/createMemoryHistory.js +0 -220
- package/lib/commonjs/createMemoryHistory.js.map +0 -1
- package/lib/commonjs/extractPathFromURL.js +0 -25
- package/lib/commonjs/extractPathFromURL.js.map +0 -1
- package/lib/commonjs/index.js +0 -129
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/theming/DarkTheme.js +0 -19
- package/lib/commonjs/theming/DarkTheme.js.map +0 -1
- package/lib/commonjs/theming/DefaultTheme.js +0 -19
- package/lib/commonjs/theming/DefaultTheme.js.map +0 -1
- package/lib/commonjs/theming/ThemeContext.js +0 -15
- package/lib/commonjs/theming/ThemeContext.js.map +0 -1
- package/lib/commonjs/theming/ThemeProvider.js +0 -20
- package/lib/commonjs/theming/ThemeProvider.js.map +0 -1
- package/lib/commonjs/theming/useTheme.js +0 -16
- package/lib/commonjs/theming/useTheme.js.map +0 -1
- package/lib/commonjs/types.js +0 -6
- package/lib/commonjs/types.js.map +0 -1
- package/lib/commonjs/useBackButton.js +0 -11
- package/lib/commonjs/useBackButton.js.map +0 -1
- package/lib/commonjs/useBackButton.native.js +0 -27
- package/lib/commonjs/useBackButton.native.js.map +0 -1
- package/lib/commonjs/useDocumentTitle.js +0 -32
- package/lib/commonjs/useDocumentTitle.js.map +0 -1
- package/lib/commonjs/useDocumentTitle.native.js +0 -10
- package/lib/commonjs/useDocumentTitle.native.js.map +0 -1
- package/lib/commonjs/useLinkBuilder.js +0 -63
- package/lib/commonjs/useLinkBuilder.js.map +0 -1
- package/lib/commonjs/useLinkProps.js +0 -97
- package/lib/commonjs/useLinkProps.js.map +0 -1
- package/lib/commonjs/useLinkTo.js +0 -45
- package/lib/commonjs/useLinkTo.js.map +0 -1
- package/lib/commonjs/useLinking.js +0 -303
- package/lib/commonjs/useLinking.js.map +0 -1
- package/lib/commonjs/useLinking.native.js +0 -152
- package/lib/commonjs/useLinking.native.js.map +0 -1
- package/lib/commonjs/useScrollToTop.js +0 -95
- package/lib/commonjs/useScrollToTop.js.map +0 -1
- package/lib/commonjs/useThenable.js +0 -41
- package/lib/commonjs/useThenable.js.map +0 -1
- package/lib/module/theming/ThemeContext.js +0 -6
- package/lib/module/theming/ThemeContext.js.map +0 -1
- package/lib/module/theming/ThemeProvider.js +0 -11
- package/lib/module/theming/ThemeProvider.js.map +0 -1
- package/lib/module/theming/useTheme.js +0 -7
- package/lib/module/theming/useTheme.js.map +0 -1
- package/lib/typescript/src/__mocks__/window.d.ts.map +0 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +0 -5
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +0 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +0 -9
- package/lib/typescript/src/theming/ThemeProvider.d.ts.map +0 -1
- package/lib/typescript/src/theming/useTheme.d.ts +0 -2
- package/lib/typescript/src/theming/useTheme.d.ts.map +0 -1
- package/src/theming/ThemeContext.tsx +0 -10
- package/src/theming/ThemeProvider.tsx +0 -15
- package/src/theming/useTheme.tsx +0 -9
package/src/useLinkProps.tsx
CHANGED
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPathFromState,
|
|
3
|
-
NavigationAction,
|
|
3
|
+
type NavigationAction,
|
|
4
4
|
NavigationContainerRefContext,
|
|
5
5
|
NavigationHelpersContext,
|
|
6
|
-
NavigatorScreenParams,
|
|
7
|
-
ParamListBase,
|
|
6
|
+
type NavigatorScreenParams,
|
|
7
|
+
type ParamListBase,
|
|
8
8
|
} from '@amazon-devices/react-navigation__core';
|
|
9
9
|
import type { NavigationState, PartialState } from '@amazon-devices/react-navigation__routers';
|
|
10
10
|
import * as React from 'react';
|
|
11
|
-
import { GestureResponderEvent, Platform } from 'react-native';
|
|
11
|
+
import { type GestureResponderEvent, Platform } from 'react-native';
|
|
12
12
|
|
|
13
|
-
import LinkingContext from './LinkingContext';
|
|
14
|
-
import useLinkTo, { To } from './useLinkTo';
|
|
13
|
+
import { LinkingContext } from './LinkingContext';
|
|
15
14
|
|
|
16
|
-
type
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
export type LinkProps<
|
|
16
|
+
ParamList extends ReactNavigation.RootParamList,
|
|
17
|
+
RouteName extends keyof ParamList = keyof ParamList,
|
|
18
|
+
> =
|
|
19
|
+
| ({
|
|
20
|
+
href?: string;
|
|
21
|
+
action?: NavigationAction;
|
|
22
|
+
} & {
|
|
23
|
+
[Screen in keyof ParamList]: undefined extends ParamList[Screen]
|
|
24
|
+
? { screen: Screen; params?: ParamList[Screen] }
|
|
25
|
+
: { screen: Screen; params: ParamList[Screen] };
|
|
26
|
+
}[RouteName])
|
|
27
|
+
| {
|
|
28
|
+
href?: string;
|
|
29
|
+
action: NavigationAction;
|
|
30
|
+
screen?: undefined;
|
|
31
|
+
params?: undefined;
|
|
32
|
+
};
|
|
20
33
|
|
|
21
34
|
const getStateFromParams = (
|
|
22
|
-
params: NavigatorScreenParams<ParamListBase
|
|
35
|
+
params: NavigatorScreenParams<ParamListBase> | undefined
|
|
23
36
|
): PartialState<NavigationState> | NavigationState | undefined => {
|
|
24
37
|
if (params?.state) {
|
|
25
38
|
return params.state;
|
|
@@ -31,11 +44,11 @@ const getStateFromParams = (
|
|
|
31
44
|
{
|
|
32
45
|
name: params.screen,
|
|
33
46
|
params: params.params,
|
|
34
|
-
// @ts-expect-error
|
|
47
|
+
// @ts-expect-error this is fine 🔥
|
|
35
48
|
state: params.screen
|
|
36
49
|
? getStateFromParams(
|
|
37
50
|
params.params as
|
|
38
|
-
| NavigatorScreenParams<ParamListBase
|
|
51
|
+
| NavigatorScreenParams<ParamListBase>
|
|
39
52
|
| undefined
|
|
40
53
|
)
|
|
41
54
|
: undefined,
|
|
@@ -50,16 +63,20 @@ const getStateFromParams = (
|
|
|
50
63
|
/**
|
|
51
64
|
* Hook to get props for an anchor tag so it can work with in page navigation.
|
|
52
65
|
*
|
|
53
|
-
* @param props.
|
|
66
|
+
* @param props.screen Name of the screen to navigate to (e.g. `'Feeds'`).
|
|
67
|
+
* @param props.params Params to pass to the screen to navigate to (e.g. `{ sort: 'hot' }`).
|
|
68
|
+
* @param props.href Optional absolute path to use for the href (e.g. `/feeds/hot`).
|
|
54
69
|
* @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
|
|
55
70
|
*/
|
|
56
|
-
export
|
|
57
|
-
|
|
58
|
-
|
|
71
|
+
export function useLinkProps<ParamList extends ReactNavigation.RootParamList>({
|
|
72
|
+
screen,
|
|
73
|
+
params,
|
|
74
|
+
href,
|
|
75
|
+
action,
|
|
76
|
+
}: LinkProps<ParamList>) {
|
|
59
77
|
const root = React.useContext(NavigationContainerRefContext);
|
|
60
78
|
const navigation = React.useContext(NavigationHelpersContext);
|
|
61
79
|
const { options } = React.useContext(LinkingContext);
|
|
62
|
-
const linkTo = useLinkTo<ParamList>();
|
|
63
80
|
|
|
64
81
|
const onPress = (
|
|
65
82
|
e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
|
|
@@ -67,18 +84,30 @@ export default function useLinkProps<
|
|
|
67
84
|
let shouldHandle = false;
|
|
68
85
|
|
|
69
86
|
if (Platform.OS !== 'web' || !e) {
|
|
70
|
-
|
|
71
|
-
} else if (
|
|
72
|
-
!e.defaultPrevented && // onPress prevented default
|
|
73
|
-
// @ts-expect-error: these properties exist on web, but not in React Native
|
|
74
|
-
!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
|
|
75
|
-
// @ts-expect-error: these properties exist on web, but not in React Native
|
|
76
|
-
(e.button == null || e.button === 0) && // ignore everything but left clicks
|
|
77
|
-
// @ts-expect-error: these properties exist on web, but not in React Native
|
|
78
|
-
[undefined, null, '', 'self'].includes(e.currentTarget?.target) // let browser handle "target=_blank" etc.
|
|
79
|
-
) {
|
|
80
|
-
e.preventDefault();
|
|
87
|
+
e?.preventDefault?.();
|
|
81
88
|
shouldHandle = true;
|
|
89
|
+
} else {
|
|
90
|
+
// ignore clicks with modifier keys
|
|
91
|
+
const hasModifierKey =
|
|
92
|
+
('metaKey' in e && e.metaKey) ||
|
|
93
|
+
('altKey' in e && e.altKey) ||
|
|
94
|
+
('ctrlKey' in e && e.ctrlKey) ||
|
|
95
|
+
('shiftKey' in e && e.shiftKey);
|
|
96
|
+
|
|
97
|
+
// only handle left clicks
|
|
98
|
+
const isLeftClick =
|
|
99
|
+
'button' in e ? e.button == null || e.button === 0 : true;
|
|
100
|
+
|
|
101
|
+
// let browser handle "target=_blank" etc.
|
|
102
|
+
const isSelfTarget =
|
|
103
|
+
e.currentTarget && 'target' in e.currentTarget
|
|
104
|
+
? [undefined, null, '', 'self'].includes(e.currentTarget.target)
|
|
105
|
+
: true;
|
|
106
|
+
|
|
107
|
+
if (!hasModifierKey && isLeftClick && isSelfTarget) {
|
|
108
|
+
e.preventDefault?.();
|
|
109
|
+
shouldHandle = true;
|
|
110
|
+
}
|
|
82
111
|
}
|
|
83
112
|
|
|
84
113
|
if (shouldHandle) {
|
|
@@ -93,34 +122,35 @@ export default function useLinkProps<
|
|
|
93
122
|
);
|
|
94
123
|
}
|
|
95
124
|
} else {
|
|
96
|
-
|
|
125
|
+
// @ts-expect-error This is already type-checked by the prop types
|
|
126
|
+
navigation?.navigate(screen, params);
|
|
97
127
|
}
|
|
98
128
|
}
|
|
99
129
|
};
|
|
100
130
|
|
|
101
131
|
const getPathFromStateHelper = options?.getPathFromState ?? getPathFromState;
|
|
102
132
|
|
|
103
|
-
const href =
|
|
104
|
-
typeof to === 'string'
|
|
105
|
-
? to
|
|
106
|
-
: getPathFromStateHelper(
|
|
107
|
-
{
|
|
108
|
-
routes: [
|
|
109
|
-
{
|
|
110
|
-
name: to.screen,
|
|
111
|
-
// @ts-expect-error
|
|
112
|
-
params: to.params,
|
|
113
|
-
// @ts-expect-error
|
|
114
|
-
state: getStateFromParams(to.params),
|
|
115
|
-
},
|
|
116
|
-
],
|
|
117
|
-
},
|
|
118
|
-
options?.config
|
|
119
|
-
);
|
|
120
|
-
|
|
121
133
|
return {
|
|
122
|
-
href
|
|
123
|
-
|
|
134
|
+
href:
|
|
135
|
+
href ??
|
|
136
|
+
(Platform.OS === 'web' && screen != null
|
|
137
|
+
? getPathFromStateHelper(
|
|
138
|
+
{
|
|
139
|
+
routes: [
|
|
140
|
+
{
|
|
141
|
+
// @ts-expect-error this is fine 🔥
|
|
142
|
+
name: screen,
|
|
143
|
+
// @ts-expect-error this is fine 🔥
|
|
144
|
+
params: params,
|
|
145
|
+
// @ts-expect-error this is fine 🔥
|
|
146
|
+
state: getStateFromParams(params),
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
options?.config
|
|
151
|
+
)
|
|
152
|
+
: undefined),
|
|
153
|
+
role: 'link' as const,
|
|
124
154
|
onPress,
|
|
125
155
|
};
|
|
126
156
|
}
|
package/src/useLinkTo.tsx
CHANGED
|
@@ -1,70 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getActionFromState,
|
|
3
|
-
getStateFromPath,
|
|
4
|
-
NavigationContainerRefContext,
|
|
5
|
-
} from '@amazon-devices/react-navigation__core';
|
|
1
|
+
import { NavigationContainerRefContext } from '@amazon-devices/react-navigation__core';
|
|
6
2
|
import * as React from 'react';
|
|
7
3
|
|
|
8
|
-
import
|
|
4
|
+
import { useLinkBuilder } from './useLinkBuilder';
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
? {
|
|
17
|
-
screen: Extract<RouteName, string>;
|
|
18
|
-
params?: ParamList[RouteName];
|
|
19
|
-
}
|
|
20
|
-
: {
|
|
21
|
-
screen: Extract<RouteName, string>;
|
|
22
|
-
params: ParamList[RouteName];
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
export default function useLinkTo<
|
|
26
|
-
ParamList extends ReactNavigation.RootParamList
|
|
27
|
-
>() {
|
|
6
|
+
/**
|
|
7
|
+
* Helper to navigate to a screen using a href based on the linking options.
|
|
8
|
+
*
|
|
9
|
+
* @returns function that receives the href to navigate to.
|
|
10
|
+
*/
|
|
11
|
+
export function useLinkTo() {
|
|
28
12
|
const navigation = React.useContext(NavigationContainerRefContext);
|
|
29
|
-
const
|
|
13
|
+
const { buildAction } = useLinkBuilder();
|
|
30
14
|
|
|
31
15
|
const linkTo = React.useCallback(
|
|
32
|
-
(
|
|
16
|
+
(href: string) => {
|
|
33
17
|
if (navigation === undefined) {
|
|
34
18
|
throw new Error(
|
|
35
19
|
"Couldn't find a navigation object. Is your component inside NavigationContainer?"
|
|
36
20
|
);
|
|
37
21
|
}
|
|
38
22
|
|
|
39
|
-
|
|
40
|
-
// @ts-expect-error: This is fine
|
|
41
|
-
navigation.navigate(to.screen, to.params);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!to.startsWith('/')) {
|
|
46
|
-
throw new Error(`The path must start with '/' (${to}).`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const { options } = linking;
|
|
50
|
-
|
|
51
|
-
const state = options?.getStateFromPath
|
|
52
|
-
? options.getStateFromPath(to, options.config)
|
|
53
|
-
: getStateFromPath(to, options?.config);
|
|
23
|
+
const action = buildAction(href);
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
const action = getActionFromState(state, options?.config);
|
|
57
|
-
|
|
58
|
-
if (action !== undefined) {
|
|
59
|
-
navigation.dispatch(action);
|
|
60
|
-
} else {
|
|
61
|
-
navigation.reset(state);
|
|
62
|
-
}
|
|
63
|
-
} else {
|
|
64
|
-
throw new Error('Failed to parse the path to a navigation state.');
|
|
65
|
-
}
|
|
25
|
+
navigation.dispatch(action);
|
|
66
26
|
},
|
|
67
|
-
[
|
|
27
|
+
[buildAction, navigation]
|
|
68
28
|
);
|
|
69
29
|
|
|
70
30
|
return linkTo;
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getActionFromState as getActionFromStateDefault,
|
|
3
3
|
getStateFromPath as getStateFromPathDefault,
|
|
4
|
-
NavigationContainerRef,
|
|
5
|
-
ParamListBase,
|
|
4
|
+
type NavigationContainerRef,
|
|
5
|
+
type ParamListBase,
|
|
6
|
+
useNavigationIndependentTree,
|
|
6
7
|
} from '@amazon-devices/react-navigation__core';
|
|
7
8
|
import * as React from 'react';
|
|
8
9
|
import { Linking, Platform } from 'react-native';
|
|
9
10
|
|
|
10
|
-
import extractPathFromURL from './extractPathFromURL';
|
|
11
|
+
import { extractPathFromURL } from './extractPathFromURL';
|
|
11
12
|
import type { LinkingOptions } from './types';
|
|
12
13
|
|
|
13
14
|
type ResultState = ReturnType<typeof getStateFromPathDefault>;
|
|
14
15
|
|
|
15
|
-
type Options = LinkingOptions<ParamListBase
|
|
16
|
-
independent?: boolean;
|
|
17
|
-
};
|
|
16
|
+
type Options = LinkingOptions<ParamListBase>;
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
const linkingHandlers: symbol[] = [];
|
|
20
19
|
|
|
21
|
-
export
|
|
22
|
-
ref: React.RefObject<NavigationContainerRef<ParamListBase
|
|
20
|
+
export function useLinking(
|
|
21
|
+
ref: React.RefObject<NavigationContainerRef<ParamListBase> | null>,
|
|
23
22
|
{
|
|
24
|
-
independent,
|
|
25
23
|
enabled = true,
|
|
26
24
|
prefixes,
|
|
27
25
|
filter,
|
|
@@ -29,11 +27,11 @@ export default function useLinking(
|
|
|
29
27
|
getInitialURL = () =>
|
|
30
28
|
Promise.race([
|
|
31
29
|
Linking.getInitialURL(),
|
|
32
|
-
new Promise<undefined>((resolve) =>
|
|
30
|
+
new Promise<undefined>((resolve) => {
|
|
33
31
|
// Timeout in 150ms if `getInitialState` doesn't resolve
|
|
34
32
|
// Workaround for https://github.com/facebook/react-native/issues/25675
|
|
35
|
-
setTimeout(resolve, 150)
|
|
36
|
-
),
|
|
33
|
+
setTimeout(resolve, 150);
|
|
34
|
+
}),
|
|
37
35
|
]),
|
|
38
36
|
subscribe = (listener) => {
|
|
39
37
|
const callback = ({ url }: { url: string }) => listener(url);
|
|
@@ -57,8 +55,11 @@ export default function useLinking(
|
|
|
57
55
|
},
|
|
58
56
|
getStateFromPath = getStateFromPathDefault,
|
|
59
57
|
getActionFromState = getActionFromStateDefault,
|
|
60
|
-
}: Options
|
|
58
|
+
}: Options,
|
|
59
|
+
onUnhandledLinking: (lastUnhandledLining: string | undefined) => void
|
|
61
60
|
) {
|
|
61
|
+
const independent = useNavigationIndependentTree();
|
|
62
|
+
|
|
62
63
|
React.useEffect(() => {
|
|
63
64
|
if (process.env.NODE_ENV === 'production') {
|
|
64
65
|
return undefined;
|
|
@@ -140,12 +141,21 @@ export default function useLinking(
|
|
|
140
141
|
if (enabledRef.current) {
|
|
141
142
|
const url = getInitialURLRef.current();
|
|
142
143
|
|
|
143
|
-
if (url != null
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
if (url != null) {
|
|
145
|
+
if (typeof url !== 'string') {
|
|
146
|
+
return url.then((url) => {
|
|
147
|
+
const state = getStateFromURL(url);
|
|
148
|
+
|
|
149
|
+
if (typeof url === 'string') {
|
|
150
|
+
// If the link were handled, it gets cleared in NavigationContainer
|
|
151
|
+
onUnhandledLinking(extractPathFromURL(prefixes, url));
|
|
152
|
+
}
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
return state;
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
onUnhandledLinking(extractPathFromURL(prefixes, url));
|
|
158
|
+
}
|
|
149
159
|
}
|
|
150
160
|
|
|
151
161
|
state = getStateFromURL(url);
|
|
@@ -161,7 +171,7 @@ export default function useLinking(
|
|
|
161
171
|
};
|
|
162
172
|
|
|
163
173
|
return thenable as PromiseLike<ResultState | undefined>;
|
|
164
|
-
}, [getStateFromURL]);
|
|
174
|
+
}, [getStateFromURL, onUnhandledLinking, prefixes]);
|
|
165
175
|
|
|
166
176
|
React.useEffect(() => {
|
|
167
177
|
const listener = (url: string) => {
|
|
@@ -173,16 +183,8 @@ export default function useLinking(
|
|
|
173
183
|
const state = navigation ? getStateFromURL(url) : undefined;
|
|
174
184
|
|
|
175
185
|
if (navigation && state) {
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
const rootState = navigation.getRootState();
|
|
179
|
-
|
|
180
|
-
if (state.routes.some((r) => !rootState?.routeNames.includes(r.name))) {
|
|
181
|
-
console.warn(
|
|
182
|
-
"The navigation state parsed from the URL contains routes not present in the root navigator. This usually means that the linking configuration doesn't match the navigation structure. See https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration."
|
|
183
|
-
);
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
+
// If the link were handled, it gets cleared in NavigationContainer
|
|
187
|
+
onUnhandledLinking(extractPathFromURL(prefixes, url));
|
|
186
188
|
|
|
187
189
|
const action = getActionFromStateRef.current(state, configRef.current);
|
|
188
190
|
|
|
@@ -207,7 +209,7 @@ export default function useLinking(
|
|
|
207
209
|
};
|
|
208
210
|
|
|
209
211
|
return subscribe(listener);
|
|
210
|
-
}, [enabled, getStateFromURL, ref, subscribe]);
|
|
212
|
+
}, [enabled, getStateFromURL, onUnhandledLinking, prefixes, ref, subscribe]);
|
|
211
213
|
|
|
212
214
|
return {
|
|
213
215
|
getInitialState,
|
package/src/useLinking.tsx
CHANGED
|
@@ -3,15 +3,16 @@ import {
|
|
|
3
3
|
getActionFromState as getActionFromStateDefault,
|
|
4
4
|
getPathFromState as getPathFromStateDefault,
|
|
5
5
|
getStateFromPath as getStateFromPathDefault,
|
|
6
|
-
NavigationContainerRef,
|
|
7
|
-
NavigationState,
|
|
8
|
-
ParamListBase,
|
|
6
|
+
type NavigationContainerRef,
|
|
7
|
+
type NavigationState,
|
|
8
|
+
type ParamListBase,
|
|
9
|
+
useNavigationIndependentTree,
|
|
9
10
|
} from '@amazon-devices/react-navigation__core';
|
|
10
11
|
import isEqual from 'fast-deep-equal';
|
|
11
12
|
import * as React from 'react';
|
|
12
13
|
|
|
13
|
-
import createMemoryHistory from './createMemoryHistory';
|
|
14
|
-
import ServerContext from './ServerContext';
|
|
14
|
+
import { createMemoryHistory } from './createMemoryHistory';
|
|
15
|
+
import { ServerContext } from './ServerContext';
|
|
15
16
|
import type { LinkingOptions } from './types';
|
|
16
17
|
|
|
17
18
|
type ResultState = ReturnType<typeof getStateFromPathDefault>;
|
|
@@ -62,28 +63,29 @@ const findMatchingState = <T extends NavigationState>(
|
|
|
62
63
|
export const series = (cb: () => Promise<void>) => {
|
|
63
64
|
let queue = Promise.resolve();
|
|
64
65
|
const callback = () => {
|
|
66
|
+
// eslint-disable-next-line promise/no-callback-in-promise
|
|
65
67
|
queue = queue.then(cb);
|
|
66
68
|
};
|
|
67
69
|
return callback;
|
|
68
70
|
};
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
const linkingHandlers: symbol[] = [];
|
|
71
73
|
|
|
72
|
-
type Options = LinkingOptions<ParamListBase
|
|
73
|
-
independent?: boolean;
|
|
74
|
-
};
|
|
74
|
+
type Options = LinkingOptions<ParamListBase>;
|
|
75
75
|
|
|
76
|
-
export
|
|
77
|
-
ref: React.RefObject<NavigationContainerRef<ParamListBase
|
|
76
|
+
export function useLinking(
|
|
77
|
+
ref: React.RefObject<NavigationContainerRef<ParamListBase> | null>,
|
|
78
78
|
{
|
|
79
|
-
independent,
|
|
80
79
|
enabled = true,
|
|
81
80
|
config,
|
|
82
81
|
getStateFromPath = getStateFromPathDefault,
|
|
83
82
|
getPathFromState = getPathFromStateDefault,
|
|
84
83
|
getActionFromState = getActionFromStateDefault,
|
|
85
|
-
}: Options
|
|
84
|
+
}: Options,
|
|
85
|
+
onUnhandledLinking: (lastUnhandledLining: string | undefined) => void
|
|
86
86
|
) {
|
|
87
|
+
const independent = useNavigationIndependentTree();
|
|
88
|
+
|
|
87
89
|
React.useEffect(() => {
|
|
88
90
|
if (process.env.NODE_ENV === 'production') {
|
|
89
91
|
return undefined;
|
|
@@ -139,6 +141,17 @@ export default function useLinking(
|
|
|
139
141
|
getActionFromStateRef.current = getActionFromState;
|
|
140
142
|
});
|
|
141
143
|
|
|
144
|
+
const validateRoutesNotExistInRootState = React.useCallback(
|
|
145
|
+
(state: ResultState) => {
|
|
146
|
+
const navigation = ref.current;
|
|
147
|
+
const rootState = navigation?.getRootState();
|
|
148
|
+
// Make sure that the routes in the state exist in the root navigator
|
|
149
|
+
// Otherwise there's an error in the linking configuration
|
|
150
|
+
return state?.routes.some((r) => !rootState?.routeNames.includes(r.name));
|
|
151
|
+
},
|
|
152
|
+
[ref]
|
|
153
|
+
);
|
|
154
|
+
|
|
142
155
|
const server = React.useContext(ServerContext);
|
|
143
156
|
|
|
144
157
|
const getInitialState = React.useCallback(() => {
|
|
@@ -154,6 +167,9 @@ export default function useLinking(
|
|
|
154
167
|
if (path) {
|
|
155
168
|
value = getStateFromPathRef.current(path, configRef.current);
|
|
156
169
|
}
|
|
170
|
+
|
|
171
|
+
// If the link were handled, it gets cleared in NavigationContainer
|
|
172
|
+
onUnhandledLinking(path);
|
|
157
173
|
}
|
|
158
174
|
|
|
159
175
|
const thenable = {
|
|
@@ -183,6 +199,8 @@ export default function useLinking(
|
|
|
183
199
|
return;
|
|
184
200
|
}
|
|
185
201
|
|
|
202
|
+
const { location } = window;
|
|
203
|
+
|
|
186
204
|
const path = location.pathname + location.search;
|
|
187
205
|
const index = history.index;
|
|
188
206
|
|
|
@@ -206,14 +224,11 @@ export default function useLinking(
|
|
|
206
224
|
// We should only dispatch an action when going forward
|
|
207
225
|
// Otherwise the action will likely add items to history, which would mess things up
|
|
208
226
|
if (state) {
|
|
227
|
+
// If the link were handled, it gets cleared in NavigationContainer
|
|
228
|
+
onUnhandledLinking(path);
|
|
209
229
|
// Make sure that the routes in the state exist in the root navigator
|
|
210
230
|
// Otherwise there's an error in the linking configuration
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (state.routes.some((r) => !rootState?.routeNames.includes(r.name))) {
|
|
214
|
-
console.warn(
|
|
215
|
-
"The navigation state parsed from the URL contains routes not present in the root navigator. This usually means that the linking configuration doesn't match the navigation structure. See https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration."
|
|
216
|
-
);
|
|
231
|
+
if (validateRoutesNotExistInRootState(state)) {
|
|
217
232
|
return;
|
|
218
233
|
}
|
|
219
234
|
|
|
@@ -248,7 +263,13 @@ export default function useLinking(
|
|
|
248
263
|
navigation.resetRoot(state);
|
|
249
264
|
}
|
|
250
265
|
});
|
|
251
|
-
}, [
|
|
266
|
+
}, [
|
|
267
|
+
enabled,
|
|
268
|
+
history,
|
|
269
|
+
onUnhandledLinking,
|
|
270
|
+
ref,
|
|
271
|
+
validateRoutesNotExistInRootState,
|
|
272
|
+
]);
|
|
252
273
|
|
|
253
274
|
React.useEffect(() => {
|
|
254
275
|
if (!enabled) {
|
|
@@ -259,6 +280,8 @@ export default function useLinking(
|
|
|
259
280
|
route: ReturnType<typeof findFocusedRoute>,
|
|
260
281
|
state: NavigationState
|
|
261
282
|
): string => {
|
|
283
|
+
let path;
|
|
284
|
+
|
|
262
285
|
// If the `route` object contains a `path`, use that path as long as `route.name` and `params` still match
|
|
263
286
|
// This makes sure that we preserve the original URL for wildcard routes
|
|
264
287
|
if (route?.path) {
|
|
@@ -275,12 +298,31 @@ export default function useLinking(
|
|
|
275
298
|
focusedRoute.name === route.name &&
|
|
276
299
|
isEqual(focusedRoute.params, route.params)
|
|
277
300
|
) {
|
|
278
|
-
|
|
301
|
+
path = route.path;
|
|
279
302
|
}
|
|
280
303
|
}
|
|
281
304
|
}
|
|
282
305
|
|
|
283
|
-
|
|
306
|
+
if (path == null) {
|
|
307
|
+
path = getPathFromStateRef.current(state, configRef.current);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const previousRoute = previousStateRef.current
|
|
311
|
+
? findFocusedRoute(previousStateRef.current)
|
|
312
|
+
: undefined;
|
|
313
|
+
|
|
314
|
+
// Preserve the hash if the route didn't change
|
|
315
|
+
if (
|
|
316
|
+
previousRoute &&
|
|
317
|
+
route &&
|
|
318
|
+
'key' in previousRoute &&
|
|
319
|
+
'key' in route &&
|
|
320
|
+
previousRoute.key === route.key
|
|
321
|
+
) {
|
|
322
|
+
path = path + location.hash;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return path;
|
|
284
326
|
};
|
|
285
327
|
|
|
286
328
|
if (ref.current) {
|
|
@@ -357,7 +399,12 @@ export default function useLinking(
|
|
|
357
399
|
const currentIndex = history.index;
|
|
358
400
|
|
|
359
401
|
try {
|
|
360
|
-
if (
|
|
402
|
+
if (
|
|
403
|
+
nextIndex !== -1 &&
|
|
404
|
+
nextIndex < currentIndex &&
|
|
405
|
+
// We should only go back if the entry exists and it's less than current index
|
|
406
|
+
history.get(nextIndex)
|
|
407
|
+
) {
|
|
361
408
|
// An existing entry for this path exists and it's less than current index, go back to that
|
|
362
409
|
await history.go(nextIndex - currentIndex);
|
|
363
410
|
} else {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { LocaleDirContext } from './LocaleDirContext';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook to access the text direction specified in the `NavigationContainer`.
|
|
7
|
+
*/
|
|
8
|
+
export function useLocale() {
|
|
9
|
+
const direction = React.useContext(LocaleDirContext);
|
|
10
|
+
|
|
11
|
+
if (direction === undefined) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
"Couldn't determine the text direction. Is your component inside NavigationContainer?"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return { direction };
|
|
18
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getPathFromState, useStateForPath } from '@amazon-devices/react-navigation__core';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { LinkingContext } from './LinkingContext';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook to get the path for the current route based on linking options.
|
|
8
|
+
*
|
|
9
|
+
* @returns Path for the current route.
|
|
10
|
+
*/
|
|
11
|
+
export function useRoutePath() {
|
|
12
|
+
const { options } = React.useContext(LinkingContext);
|
|
13
|
+
const state = useStateForPath();
|
|
14
|
+
|
|
15
|
+
if (state === undefined) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
"Couldn't find a state for the route object. Is your component inside a screen in a navigator?"
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const getPathFromStateHelper = options?.getPathFromState ?? getPathFromState;
|
|
22
|
+
|
|
23
|
+
const path = React.useMemo(() => {
|
|
24
|
+
if (options?.enabled === false) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const path = getPathFromStateHelper(state, options?.config);
|
|
29
|
+
|
|
30
|
+
return path;
|
|
31
|
+
}, [options?.enabled, options?.config, state, getPathFromStateHelper]);
|
|
32
|
+
|
|
33
|
+
return path;
|
|
34
|
+
}
|