@amazon-devices/react-navigation__native 2.0.1758683737

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.
Files changed (189) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +5 -0
  3. package/SystemBundles/6132afb62bda3afb78ba1a1aca51924df73e9dbcc77106aa0f97a0ef68b04ebb.bundle +15196 -0
  4. package/SystemBundles/6132afb62bda3afb78ba1a1aca51924df73e9dbcc77106aa0f97a0ef68b04ebb.map +1 -0
  5. package/SystemModules/amzn__react-navigation__native-2.modules.txt +76 -0
  6. package/SystemModules/amzn__react-navigation__native-2.private.modules.txt +101 -0
  7. package/SystemModules/keplerscript-system-bundle-config.json +7 -0
  8. package/THIRD_PARTY_NOTICES.txt +24 -0
  9. package/kepler-compatibility.json +8 -0
  10. package/kepler-transformed-package-info.json +3 -0
  11. package/lib/commonjs/Link.js +50 -0
  12. package/lib/commonjs/Link.js.map +1 -0
  13. package/lib/commonjs/LinkingContext.js +15 -0
  14. package/lib/commonjs/LinkingContext.js.map +1 -0
  15. package/lib/commonjs/NavigationContainer.js +109 -0
  16. package/lib/commonjs/NavigationContainer.js.map +1 -0
  17. package/lib/commonjs/ServerContainer.js +54 -0
  18. package/lib/commonjs/ServerContainer.js.map +1 -0
  19. package/lib/commonjs/ServerContext.js +12 -0
  20. package/lib/commonjs/ServerContext.js.map +1 -0
  21. package/lib/commonjs/createMemoryHistory.js +220 -0
  22. package/lib/commonjs/createMemoryHistory.js.map +1 -0
  23. package/lib/commonjs/extractPathFromURL.js +25 -0
  24. package/lib/commonjs/extractPathFromURL.js.map +1 -0
  25. package/lib/commonjs/index.js +129 -0
  26. package/lib/commonjs/index.js.map +1 -0
  27. package/lib/commonjs/theming/DarkTheme.js +19 -0
  28. package/lib/commonjs/theming/DarkTheme.js.map +1 -0
  29. package/lib/commonjs/theming/DefaultTheme.js +19 -0
  30. package/lib/commonjs/theming/DefaultTheme.js.map +1 -0
  31. package/lib/commonjs/theming/ThemeContext.js +15 -0
  32. package/lib/commonjs/theming/ThemeContext.js.map +1 -0
  33. package/lib/commonjs/theming/ThemeProvider.js +20 -0
  34. package/lib/commonjs/theming/ThemeProvider.js.map +1 -0
  35. package/lib/commonjs/theming/useTheme.js +16 -0
  36. package/lib/commonjs/theming/useTheme.js.map +1 -0
  37. package/lib/commonjs/types.js +6 -0
  38. package/lib/commonjs/types.js.map +1 -0
  39. package/lib/commonjs/useBackButton.js +11 -0
  40. package/lib/commonjs/useBackButton.js.map +1 -0
  41. package/lib/commonjs/useBackButton.native.js +27 -0
  42. package/lib/commonjs/useBackButton.native.js.map +1 -0
  43. package/lib/commonjs/useDocumentTitle.js +32 -0
  44. package/lib/commonjs/useDocumentTitle.js.map +1 -0
  45. package/lib/commonjs/useDocumentTitle.native.js +10 -0
  46. package/lib/commonjs/useDocumentTitle.native.js.map +1 -0
  47. package/lib/commonjs/useLinkBuilder.js +63 -0
  48. package/lib/commonjs/useLinkBuilder.js.map +1 -0
  49. package/lib/commonjs/useLinkProps.js +97 -0
  50. package/lib/commonjs/useLinkProps.js.map +1 -0
  51. package/lib/commonjs/useLinkTo.js +45 -0
  52. package/lib/commonjs/useLinkTo.js.map +1 -0
  53. package/lib/commonjs/useLinking.js +303 -0
  54. package/lib/commonjs/useLinking.js.map +1 -0
  55. package/lib/commonjs/useLinking.native.js +152 -0
  56. package/lib/commonjs/useLinking.native.js.map +1 -0
  57. package/lib/commonjs/useScrollToTop.js +95 -0
  58. package/lib/commonjs/useScrollToTop.js.map +1 -0
  59. package/lib/commonjs/useThenable.js +41 -0
  60. package/lib/commonjs/useThenable.js.map +1 -0
  61. package/lib/module/Link.js +41 -0
  62. package/lib/module/Link.js.map +1 -0
  63. package/lib/module/LinkingContext.js +7 -0
  64. package/lib/module/LinkingContext.js.map +1 -0
  65. package/lib/module/NavigationContainer.js +100 -0
  66. package/lib/module/NavigationContainer.js.map +1 -0
  67. package/lib/module/ServerContainer.js +45 -0
  68. package/lib/module/ServerContainer.js.map +1 -0
  69. package/lib/module/ServerContext.js +4 -0
  70. package/lib/module/ServerContext.js.map +1 -0
  71. package/lib/module/createMemoryHistory.js +214 -0
  72. package/lib/module/createMemoryHistory.js.map +1 -0
  73. package/lib/module/extractPathFromURL.js +18 -0
  74. package/lib/module/extractPathFromURL.js.map +1 -0
  75. package/lib/module/index.js +15 -0
  76. package/lib/module/index.js.map +1 -0
  77. package/lib/module/theming/DarkTheme.js +13 -0
  78. package/lib/module/theming/DarkTheme.js.map +1 -0
  79. package/lib/module/theming/DefaultTheme.js +13 -0
  80. package/lib/module/theming/DefaultTheme.js.map +1 -0
  81. package/lib/module/theming/ThemeContext.js +6 -0
  82. package/lib/module/theming/ThemeContext.js.map +1 -0
  83. package/lib/module/theming/ThemeProvider.js +11 -0
  84. package/lib/module/theming/ThemeProvider.js.map +1 -0
  85. package/lib/module/theming/useTheme.js +7 -0
  86. package/lib/module/theming/useTheme.js.map +1 -0
  87. package/lib/module/types.js +2 -0
  88. package/lib/module/types.js.map +1 -0
  89. package/lib/module/useBackButton.js +5 -0
  90. package/lib/module/useBackButton.js.map +1 -0
  91. package/lib/module/useBackButton.native.js +19 -0
  92. package/lib/module/useBackButton.native.js.map +1 -0
  93. package/lib/module/useDocumentTitle.js +24 -0
  94. package/lib/module/useDocumentTitle.js.map +1 -0
  95. package/lib/module/useDocumentTitle.native.js +4 -0
  96. package/lib/module/useDocumentTitle.native.js.map +1 -0
  97. package/lib/module/useLinkBuilder.js +54 -0
  98. package/lib/module/useLinkBuilder.js.map +1 -0
  99. package/lib/module/useLinkProps.js +88 -0
  100. package/lib/module/useLinkProps.js.map +1 -0
  101. package/lib/module/useLinkTo.js +36 -0
  102. package/lib/module/useLinkTo.js.map +1 -0
  103. package/lib/module/useLinking.js +292 -0
  104. package/lib/module/useLinking.js.map +1 -0
  105. package/lib/module/useLinking.native.js +143 -0
  106. package/lib/module/useLinking.native.js.map +1 -0
  107. package/lib/module/useScrollToTop.js +87 -0
  108. package/lib/module/useScrollToTop.js.map +1 -0
  109. package/lib/module/useThenable.js +33 -0
  110. package/lib/module/useThenable.js.map +1 -0
  111. package/lib/typescript/src/Link.d.ts +24 -0
  112. package/lib/typescript/src/Link.d.ts.map +1 -0
  113. package/lib/typescript/src/LinkingContext.d.ts +8 -0
  114. package/lib/typescript/src/LinkingContext.d.ts.map +1 -0
  115. package/lib/typescript/src/NavigationContainer.d.ts +26 -0
  116. package/lib/typescript/src/NavigationContainer.d.ts.map +1 -0
  117. package/lib/typescript/src/ServerContainer.d.ts +15 -0
  118. package/lib/typescript/src/ServerContainer.d.ts.map +1 -0
  119. package/lib/typescript/src/ServerContext.d.ts +10 -0
  120. package/lib/typescript/src/ServerContext.d.ts.map +1 -0
  121. package/lib/typescript/src/__mocks__/window.d.ts +19 -0
  122. package/lib/typescript/src/__mocks__/window.d.ts.map +1 -0
  123. package/lib/typescript/src/createMemoryHistory.d.ts +25 -0
  124. package/lib/typescript/src/createMemoryHistory.d.ts.map +1 -0
  125. package/lib/typescript/src/extractPathFromURL.d.ts +2 -0
  126. package/lib/typescript/src/extractPathFromURL.d.ts.map +1 -0
  127. package/lib/typescript/src/index.d.ts +15 -0
  128. package/lib/typescript/src/index.d.ts.map +1 -0
  129. package/lib/typescript/src/theming/DarkTheme.d.ts +4 -0
  130. package/lib/typescript/src/theming/DarkTheme.d.ts.map +1 -0
  131. package/lib/typescript/src/theming/DefaultTheme.d.ts +4 -0
  132. package/lib/typescript/src/theming/DefaultTheme.d.ts.map +1 -0
  133. package/lib/typescript/src/theming/ThemeContext.d.ts +5 -0
  134. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -0
  135. package/lib/typescript/src/theming/ThemeProvider.d.ts +9 -0
  136. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -0
  137. package/lib/typescript/src/theming/useTheme.d.ts +2 -0
  138. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -0
  139. package/lib/typescript/src/types.d.ts +127 -0
  140. package/lib/typescript/src/types.d.ts.map +1 -0
  141. package/lib/typescript/src/useBackButton.d.ts +4 -0
  142. package/lib/typescript/src/useBackButton.d.ts.map +1 -0
  143. package/lib/typescript/src/useBackButton.native.d.ts +4 -0
  144. package/lib/typescript/src/useBackButton.native.d.ts.map +1 -0
  145. package/lib/typescript/src/useDocumentTitle.d.ts +8 -0
  146. package/lib/typescript/src/useDocumentTitle.d.ts.map +1 -0
  147. package/lib/typescript/src/useDocumentTitle.native.d.ts +2 -0
  148. package/lib/typescript/src/useDocumentTitle.native.d.ts.map +1 -0
  149. package/lib/typescript/src/useLinkBuilder.d.ts +6 -0
  150. package/lib/typescript/src/useLinkBuilder.d.ts.map +1 -0
  151. package/lib/typescript/src/useLinkProps.d.ts +21 -0
  152. package/lib/typescript/src/useLinkProps.d.ts.map +1 -0
  153. package/lib/typescript/src/useLinkTo.d.ts +9 -0
  154. package/lib/typescript/src/useLinkTo.d.ts.map +1 -0
  155. package/lib/typescript/src/useLinking.d.ts +55 -0
  156. package/lib/typescript/src/useLinking.d.ts.map +1 -0
  157. package/lib/typescript/src/useLinking.native.d.ts +51 -0
  158. package/lib/typescript/src/useLinking.native.d.ts.map +1 -0
  159. package/lib/typescript/src/useScrollToTop.d.ts +27 -0
  160. package/lib/typescript/src/useScrollToTop.d.ts.map +1 -0
  161. package/lib/typescript/src/useThenable.d.ts +2 -0
  162. package/lib/typescript/src/useThenable.d.ts.map +1 -0
  163. package/package.json +1 -0
  164. package/src/Link.tsx +53 -0
  165. package/src/LinkingContext.tsx +12 -0
  166. package/src/NavigationContainer.tsx +152 -0
  167. package/src/ServerContainer.tsx +56 -0
  168. package/src/ServerContext.tsx +14 -0
  169. package/src/__mocks__/window.tsx +77 -0
  170. package/src/createMemoryHistory.tsx +224 -0
  171. package/src/extractPathFromURL.tsx +29 -0
  172. package/src/index.tsx +14 -0
  173. package/src/theming/DarkTheme.tsx +15 -0
  174. package/src/theming/DefaultTheme.tsx +15 -0
  175. package/src/theming/ThemeContext.tsx +10 -0
  176. package/src/theming/ThemeProvider.tsx +15 -0
  177. package/src/theming/useTheme.tsx +9 -0
  178. package/src/types.tsx +145 -0
  179. package/src/useBackButton.native.tsx +33 -0
  180. package/src/useBackButton.tsx +11 -0
  181. package/src/useDocumentTitle.native.tsx +3 -0
  182. package/src/useDocumentTitle.tsx +41 -0
  183. package/src/useLinkBuilder.tsx +82 -0
  184. package/src/useLinkProps.tsx +126 -0
  185. package/src/useLinkTo.tsx +71 -0
  186. package/src/useLinking.native.tsx +215 -0
  187. package/src/useLinking.tsx +395 -0
  188. package/src/useScrollToTop.tsx +116 -0
  189. package/src/useThenable.tsx +41 -0
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+
3
+ import type { Theme } from '../types';
4
+ import ThemeContext from './ThemeContext';
5
+
6
+ type Props = {
7
+ value: Theme;
8
+ children: React.ReactNode;
9
+ };
10
+
11
+ export default function ThemeProvider({ value, children }: Props) {
12
+ return (
13
+ <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
14
+ );
15
+ }
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+
3
+ import ThemeContext from './ThemeContext';
4
+
5
+ export default function useTheme() {
6
+ const theme = React.useContext(ThemeContext);
7
+
8
+ return theme;
9
+ }
package/src/types.tsx ADDED
@@ -0,0 +1,145 @@
1
+ import type {
2
+ getActionFromState as getActionFromStateDefault,
3
+ getPathFromState as getPathFromStateDefault,
4
+ getStateFromPath as getStateFromPathDefault,
5
+ PathConfigMap,
6
+ Route,
7
+ } from '@amazon-devices/react-navigation__core';
8
+
9
+ export type Theme = {
10
+ dark: boolean;
11
+ colors: {
12
+ primary: string;
13
+ background: string;
14
+ card: string;
15
+ text: string;
16
+ border: string;
17
+ notification: string;
18
+ };
19
+ };
20
+
21
+ export type LinkingOptions<ParamList extends {}> = {
22
+ /**
23
+ * Whether deep link handling should be enabled.
24
+ * Defaults to true.
25
+ */
26
+ enabled?: boolean;
27
+ /**
28
+ * The prefixes are stripped from the URL before parsing them.
29
+ * Usually they are the `scheme` + `host` (e.g. `myapp://chat?user=jane`)
30
+ *
31
+ * This is not supported on Web.
32
+ *
33
+ * @example
34
+ * ```js
35
+ * {
36
+ * prefixes: [
37
+ * "myapp://", // App-specific scheme
38
+ * "https://example.com", // Prefix for universal links
39
+ * "https://*.example.com" // Prefix which matches any subdomain
40
+ * ]
41
+ * }
42
+ * ```
43
+ */
44
+ prefixes: string[];
45
+ /**
46
+ * Optional function which takes an incoming URL returns a boolean
47
+ * indicating whether React Navigation should handle it.
48
+ *
49
+ * This can be used to disable deep linking for specific URLs.
50
+ * e.g. URLs used for authentication, and not for deep linking to screens.
51
+ *
52
+ * This is not supported on Web.
53
+ *
54
+ * @example
55
+ * ```js
56
+ * {
57
+ * // Filter out URLs used by expo-auth-session
58
+ * filter: (url) => !url.includes('+expo-auth-session')
59
+ * }
60
+ * ```
61
+ */
62
+ filter?: (url: string) => boolean;
63
+ /**
64
+ * Config to fine-tune how to parse the path.
65
+ *
66
+ * @example
67
+ * ```js
68
+ * {
69
+ * Chat: {
70
+ * path: 'chat/:author/:id',
71
+ * parse: { id: Number }
72
+ * }
73
+ * }
74
+ * ```
75
+ */
76
+ config?: {
77
+ initialRouteName?: keyof ParamList;
78
+ screens: PathConfigMap<ParamList>;
79
+ };
80
+ /**
81
+ * Custom function to get the initial URL used for linking.
82
+ * Uses `Linking.getInitialURL()` by default.
83
+ *
84
+ * This is not supported on Web.
85
+ *
86
+ * @example
87
+ * ```js
88
+ * {
89
+ * getInitialURL () => Linking.getInitialURL(),
90
+ * }
91
+ * ```
92
+ */
93
+ getInitialURL?: () =>
94
+ | string
95
+ | null
96
+ | undefined
97
+ | Promise<string | null | undefined>;
98
+ /**
99
+ * Custom function to get subscribe to URL updates.
100
+ * Uses `Linking.addEventListener('url', callback)` by default.
101
+ *
102
+ * This is not supported on Web.
103
+ *
104
+ * @example
105
+ * ```js
106
+ * {
107
+ * subscribe: (listener) => {
108
+ * const onReceiveURL = ({ url }) => listener(url);
109
+ *
110
+ * Linking.addEventListener('url', onReceiveURL);
111
+ *
112
+ * return () => Linking.removeEventListener('url', onReceiveURL);
113
+ * }
114
+ * }
115
+ * ```
116
+ */
117
+ subscribe?: (
118
+ listener: (url: string) => void
119
+ ) => undefined | void | (() => void);
120
+ /**
121
+ * Custom function to parse the URL to a valid navigation state (advanced).
122
+ */
123
+ getStateFromPath?: typeof getStateFromPathDefault;
124
+ /**
125
+ * Custom function to convert the state object to a valid URL (advanced).
126
+ * Only applicable on Web.
127
+ */
128
+ getPathFromState?: typeof getPathFromStateDefault;
129
+ /**
130
+ * Custom function to convert the state object to a valid action (advanced).
131
+ */
132
+ getActionFromState?: typeof getActionFromStateDefault;
133
+ };
134
+
135
+ export type DocumentTitleOptions = {
136
+ enabled?: boolean;
137
+ formatter?: (
138
+ options: Record<string, any> | undefined,
139
+ route: Route<string> | undefined
140
+ ) => string;
141
+ };
142
+
143
+ export type ServerContainerRef = {
144
+ getCurrentOptions(): Record<string, any> | undefined;
145
+ };
@@ -0,0 +1,33 @@
1
+ import type {
2
+ NavigationContainerRef,
3
+ ParamListBase,
4
+ } from '@amazon-devices/react-navigation__core';
5
+ import * as React from 'react';
6
+ import { BackHandler } from 'react-native';
7
+
8
+ export default function useBackButton(
9
+ ref: React.RefObject<NavigationContainerRef<ParamListBase>>
10
+ ) {
11
+ React.useEffect(() => {
12
+ const subscription = BackHandler.addEventListener(
13
+ 'hardwareBackPress',
14
+ () => {
15
+ const navigation = ref.current;
16
+
17
+ if (navigation == null) {
18
+ return false;
19
+ }
20
+
21
+ if (navigation.canGoBack()) {
22
+ navigation.goBack();
23
+
24
+ return true;
25
+ }
26
+
27
+ return false;
28
+ }
29
+ );
30
+
31
+ return () => subscription.remove();
32
+ }, [ref]);
33
+ }
@@ -0,0 +1,11 @@
1
+ import type {
2
+ NavigationContainerRef,
3
+ ParamListBase,
4
+ } from '@amazon-devices/react-navigation__core';
5
+
6
+ export default function useBackButton(
7
+ _: React.RefObject<NavigationContainerRef<ParamListBase>>
8
+ ) {
9
+ // No-op
10
+ // BackHandler is not available on web
11
+ }
@@ -0,0 +1,3 @@
1
+ export default function useDocumentTitle() {
2
+ // Noop for React Native
3
+ }
@@ -0,0 +1,41 @@
1
+ import type {
2
+ NavigationContainerRef,
3
+ ParamListBase,
4
+ } from '@amazon-devices/react-navigation__core';
5
+ import * as React from 'react';
6
+
7
+ import type { DocumentTitleOptions } from './types';
8
+
9
+ /**
10
+ * Set the document title for the active screen
11
+ */
12
+ export default function useDocumentTitle(
13
+ ref: React.RefObject<NavigationContainerRef<ParamListBase>>,
14
+ {
15
+ enabled = true,
16
+ formatter = (options, route) => options?.title ?? route?.name,
17
+ }: DocumentTitleOptions = {}
18
+ ) {
19
+ React.useEffect(() => {
20
+ if (!enabled) {
21
+ return;
22
+ }
23
+
24
+ const navigation = ref.current;
25
+
26
+ if (navigation) {
27
+ const title = formatter(
28
+ navigation.getCurrentOptions(),
29
+ navigation.getCurrentRoute()
30
+ );
31
+
32
+ document.title = title;
33
+ }
34
+
35
+ return navigation?.addListener('options', (e) => {
36
+ const title = formatter(e.data.options, navigation?.getCurrentRoute());
37
+
38
+ document.title = title;
39
+ });
40
+ });
41
+ }
@@ -0,0 +1,82 @@
1
+ import {
2
+ getPathFromState,
3
+ NavigationHelpers,
4
+ NavigationHelpersContext,
5
+ NavigationProp,
6
+ ParamListBase,
7
+ } from '@amazon-devices/react-navigation__core';
8
+ import * as React from 'react';
9
+
10
+ import LinkingContext from './LinkingContext';
11
+
12
+ type NavigationObject =
13
+ | NavigationHelpers<ParamListBase>
14
+ | NavigationProp<ParamListBase>;
15
+
16
+ type MinimalState = {
17
+ index: number;
18
+ routes: { name: string; params?: object; state?: MinimalState }[];
19
+ };
20
+
21
+ const getRootStateForNavigate = (
22
+ navigation: NavigationObject,
23
+ state: MinimalState
24
+ ): MinimalState => {
25
+ const parent = navigation.getParent();
26
+
27
+ if (parent) {
28
+ const parentState = parent.getState();
29
+
30
+ return getRootStateForNavigate(parent, {
31
+ index: 0,
32
+ routes: [
33
+ {
34
+ ...parentState.routes[parentState.index],
35
+ state: state,
36
+ },
37
+ ],
38
+ });
39
+ }
40
+
41
+ return state;
42
+ };
43
+
44
+ /**
45
+ * Build destination link for a navigate action.
46
+ * Useful for showing anchor tags on the web for buttons that perform navigation.
47
+ */
48
+ export default function useLinkBuilder() {
49
+ const navigation = React.useContext(NavigationHelpersContext);
50
+ const linking = React.useContext(LinkingContext);
51
+
52
+ const buildLink = React.useCallback(
53
+ (name: string, params?: object) => {
54
+ const { options } = linking;
55
+
56
+ if (options?.enabled === false) {
57
+ return undefined;
58
+ }
59
+
60
+ const state = navigation
61
+ ? getRootStateForNavigate(navigation, {
62
+ index: 0,
63
+ routes: [{ name, params }],
64
+ })
65
+ : // If we couldn't find a navigation object in context, we're at root
66
+ // So we'll construct a basic state object to use
67
+ {
68
+ index: 0,
69
+ routes: [{ name, params }],
70
+ };
71
+
72
+ const path = options?.getPathFromState
73
+ ? options.getPathFromState(state, options?.config)
74
+ : getPathFromState(state, options?.config);
75
+
76
+ return path;
77
+ },
78
+ [linking, navigation]
79
+ );
80
+
81
+ return buildLink;
82
+ }
@@ -0,0 +1,126 @@
1
+ import {
2
+ getPathFromState,
3
+ NavigationAction,
4
+ NavigationContainerRefContext,
5
+ NavigationHelpersContext,
6
+ NavigatorScreenParams,
7
+ ParamListBase,
8
+ } from '@amazon-devices/react-navigation__core';
9
+ import type { NavigationState, PartialState } from '@amazon-devices/react-navigation__routers';
10
+ import * as React from 'react';
11
+ import { GestureResponderEvent, Platform } from 'react-native';
12
+
13
+ import LinkingContext from './LinkingContext';
14
+ import useLinkTo, { To } from './useLinkTo';
15
+
16
+ type Props<ParamList extends ReactNavigation.RootParamList> = {
17
+ to: To<ParamList>;
18
+ action?: NavigationAction;
19
+ };
20
+
21
+ const getStateFromParams = (
22
+ params: NavigatorScreenParams<ParamListBase, NavigationState> | undefined
23
+ ): PartialState<NavigationState> | NavigationState | undefined => {
24
+ if (params?.state) {
25
+ return params.state;
26
+ }
27
+
28
+ if (params?.screen) {
29
+ return {
30
+ routes: [
31
+ {
32
+ name: params.screen,
33
+ params: params.params,
34
+ // @ts-expect-error
35
+ state: params.screen
36
+ ? getStateFromParams(
37
+ params.params as
38
+ | NavigatorScreenParams<ParamListBase, NavigationState>
39
+ | undefined
40
+ )
41
+ : undefined,
42
+ },
43
+ ],
44
+ };
45
+ }
46
+
47
+ return undefined;
48
+ };
49
+
50
+ /**
51
+ * Hook to get props for an anchor tag so it can work with in page navigation.
52
+ *
53
+ * @param props.to Absolute path to screen (e.g. `/feeds/hot`).
54
+ * @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
+ */
56
+ export default function useLinkProps<
57
+ ParamList extends ReactNavigation.RootParamList
58
+ >({ to, action }: Props<ParamList>) {
59
+ const root = React.useContext(NavigationContainerRefContext);
60
+ const navigation = React.useContext(NavigationHelpersContext);
61
+ const { options } = React.useContext(LinkingContext);
62
+ const linkTo = useLinkTo<ParamList>();
63
+
64
+ const onPress = (
65
+ e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
66
+ ) => {
67
+ let shouldHandle = false;
68
+
69
+ if (Platform.OS !== 'web' || !e) {
70
+ shouldHandle = e ? !e.defaultPrevented : true;
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();
81
+ shouldHandle = true;
82
+ }
83
+
84
+ if (shouldHandle) {
85
+ if (action) {
86
+ if (navigation) {
87
+ navigation.dispatch(action);
88
+ } else if (root) {
89
+ root.dispatch(action);
90
+ } else {
91
+ throw new Error(
92
+ "Couldn't find a navigation object. Is your component inside NavigationContainer?"
93
+ );
94
+ }
95
+ } else {
96
+ linkTo(to);
97
+ }
98
+ }
99
+ };
100
+
101
+ const getPathFromStateHelper = options?.getPathFromState ?? getPathFromState;
102
+
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
+ return {
122
+ href,
123
+ accessibilityRole: 'link' as const,
124
+ onPress,
125
+ };
126
+ }
@@ -0,0 +1,71 @@
1
+ import {
2
+ getActionFromState,
3
+ getStateFromPath,
4
+ NavigationContainerRefContext,
5
+ } from '@amazon-devices/react-navigation__core';
6
+ import * as React from 'react';
7
+
8
+ import LinkingContext from './LinkingContext';
9
+
10
+ export type To<
11
+ ParamList extends ReactNavigation.RootParamList = ReactNavigation.RootParamList,
12
+ RouteName extends keyof ParamList = keyof ParamList
13
+ > =
14
+ | string
15
+ | (undefined extends ParamList[RouteName]
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
+ >() {
28
+ const navigation = React.useContext(NavigationContainerRefContext);
29
+ const linking = React.useContext(LinkingContext);
30
+
31
+ const linkTo = React.useCallback(
32
+ (to: To<ParamList>) => {
33
+ if (navigation === undefined) {
34
+ throw new Error(
35
+ "Couldn't find a navigation object. Is your component inside NavigationContainer?"
36
+ );
37
+ }
38
+
39
+ if (typeof to !== 'string') {
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);
54
+
55
+ if (state) {
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
+ }
66
+ },
67
+ [linking, navigation]
68
+ );
69
+
70
+ return linkTo;
71
+ }