@react-navigation/native 7.0.0-alpha.0 → 7.0.0-alpha.10

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 (238) hide show
  1. package/lib/commonjs/Link.js +16 -9
  2. package/lib/commonjs/Link.js.map +1 -1
  3. package/lib/commonjs/LinkingContext.js +8 -7
  4. package/lib/commonjs/LinkingContext.js.map +1 -1
  5. package/lib/commonjs/LocaleDirContext.js +12 -0
  6. package/lib/commonjs/LocaleDirContext.js.map +1 -0
  7. package/lib/commonjs/NavigationContainer.js +68 -32
  8. package/lib/commonjs/NavigationContainer.js.map +1 -1
  9. package/lib/commonjs/ServerContainer.js +6 -8
  10. package/lib/commonjs/ServerContainer.js.map +1 -1
  11. package/lib/commonjs/ServerContext.js +4 -6
  12. package/lib/commonjs/ServerContext.js.map +1 -1
  13. package/lib/commonjs/UnhandledLinkingContext.js +20 -0
  14. package/lib/commonjs/UnhandledLinkingContext.js.map +1 -0
  15. package/lib/commonjs/__stubs__/createStackNavigator.js +19 -0
  16. package/lib/commonjs/__stubs__/createStackNavigator.js.map +1 -0
  17. package/lib/commonjs/__stubs__/window.js +79 -0
  18. package/lib/commonjs/__stubs__/window.js.map +1 -0
  19. package/lib/commonjs/createMemoryHistory.js +5 -8
  20. package/lib/commonjs/createMemoryHistory.js.map +1 -1
  21. package/lib/commonjs/createStaticNavigation.js +8 -8
  22. package/lib/commonjs/createStaticNavigation.js.map +1 -1
  23. package/lib/commonjs/extractPathFromURL.js +4 -4
  24. package/lib/commonjs/extractPathFromURL.js.map +1 -1
  25. package/lib/commonjs/index.js +33 -34
  26. package/lib/commonjs/index.js.map +1 -1
  27. package/lib/commonjs/theming/DarkTheme.js +5 -5
  28. package/lib/commonjs/theming/DarkTheme.js.map +1 -1
  29. package/lib/commonjs/theming/DefaultTheme.js +5 -5
  30. package/lib/commonjs/theming/DefaultTheme.js.map +1 -1
  31. package/lib/commonjs/theming/fonts.js +65 -0
  32. package/lib/commonjs/theming/fonts.js.map +1 -0
  33. package/lib/commonjs/types.js.map +1 -1
  34. package/lib/commonjs/useBackButton.js +4 -20
  35. package/lib/commonjs/useBackButton.js.map +1 -1
  36. package/lib/commonjs/useBackButton.native.js +27 -0
  37. package/lib/commonjs/useBackButton.native.js.map +1 -0
  38. package/lib/commonjs/useDocumentTitle.js +6 -6
  39. package/lib/commonjs/useDocumentTitle.js.map +1 -1
  40. package/lib/commonjs/useDocumentTitle.native.js +1 -1
  41. package/lib/commonjs/useDocumentTitle.native.js.map +1 -1
  42. package/lib/commonjs/useLinkBuilder.js +80 -0
  43. package/lib/commonjs/useLinkBuilder.js.map +1 -0
  44. package/lib/commonjs/useLinkProps.js +23 -27
  45. package/lib/commonjs/useLinkProps.js.map +1 -1
  46. package/lib/commonjs/useLinkTo.js +30 -0
  47. package/lib/commonjs/useLinkTo.js.map +1 -0
  48. package/lib/commonjs/useLinking.js +39 -40
  49. package/lib/commonjs/useLinking.js.map +1 -1
  50. package/lib/commonjs/useLinking.native.js +33 -27
  51. package/lib/commonjs/useLinking.native.js.map +1 -1
  52. package/lib/commonjs/useLocale.js +23 -0
  53. package/lib/commonjs/useLocale.js.map +1 -0
  54. package/lib/commonjs/useScrollToTop.js +9 -7
  55. package/lib/commonjs/useScrollToTop.js.map +1 -1
  56. package/lib/commonjs/useThenable.js +4 -3
  57. package/lib/commonjs/useThenable.js.map +1 -1
  58. package/lib/commonjs/useUnhandledLinking.js +75 -0
  59. package/lib/commonjs/useUnhandledLinking.js.map +1 -0
  60. package/lib/module/Link.js +13 -5
  61. package/lib/module/Link.js.map +1 -1
  62. package/lib/module/LinkingContext.js +5 -3
  63. package/lib/module/LinkingContext.js.map +1 -1
  64. package/lib/module/LocaleDirContext.js +4 -0
  65. package/lib/module/LocaleDirContext.js.map +1 -0
  66. package/lib/module/NavigationContainer.js +60 -23
  67. package/lib/module/NavigationContainer.js.map +1 -1
  68. package/lib/module/ServerContainer.js +2 -2
  69. package/lib/module/ServerContainer.js.map +1 -1
  70. package/lib/module/ServerContext.js +1 -2
  71. package/lib/module/ServerContext.js.map +1 -1
  72. package/lib/module/UnhandledLinkingContext.js +12 -0
  73. package/lib/module/UnhandledLinkingContext.js.map +1 -0
  74. package/lib/module/__stubs__/createStackNavigator.js +11 -0
  75. package/lib/module/__stubs__/createStackNavigator.js.map +1 -0
  76. package/lib/module/__stubs__/window.js +73 -0
  77. package/lib/module/__stubs__/window.js.map +1 -0
  78. package/lib/module/createMemoryHistory.js +5 -8
  79. package/lib/module/createMemoryHistory.js.map +1 -1
  80. package/lib/module/createStaticNavigation.js +5 -4
  81. package/lib/module/createStaticNavigation.js.map +1 -1
  82. package/lib/module/extractPathFromURL.js +4 -4
  83. package/lib/module/extractPathFromURL.js.map +1 -1
  84. package/lib/module/index.js +12 -12
  85. package/lib/module/index.js.map +1 -1
  86. package/lib/module/theming/DarkTheme.js +4 -3
  87. package/lib/module/theming/DarkTheme.js.map +1 -1
  88. package/lib/module/theming/DefaultTheme.js +4 -3
  89. package/lib/module/theming/DefaultTheme.js.map +1 -1
  90. package/lib/module/theming/fonts.js +59 -0
  91. package/lib/module/theming/fonts.js.map +1 -0
  92. package/lib/module/types.js.map +1 -1
  93. package/lib/module/useBackButton.js +3 -17
  94. package/lib/module/useBackButton.js.map +1 -1
  95. package/lib/module/useBackButton.native.js +19 -0
  96. package/lib/module/useBackButton.native.js.map +1 -0
  97. package/lib/module/useDocumentTitle.js +4 -4
  98. package/lib/module/useDocumentTitle.js.map +1 -1
  99. package/lib/module/useDocumentTitle.native.js +1 -1
  100. package/lib/module/useDocumentTitle.native.js.map +1 -1
  101. package/lib/module/{useLinkTools.js → useLinkBuilder.js} +11 -11
  102. package/lib/module/useLinkBuilder.js.map +1 -0
  103. package/lib/module/useLinkProps.js +20 -23
  104. package/lib/module/useLinkProps.js.map +1 -1
  105. package/lib/module/useLinkTo.js +23 -0
  106. package/lib/module/useLinkTo.js.map +1 -0
  107. package/lib/module/useLinking.js +33 -36
  108. package/lib/module/useLinking.js.map +1 -1
  109. package/lib/module/useLinking.native.js +29 -22
  110. package/lib/module/useLinking.native.js.map +1 -1
  111. package/lib/module/useLocale.js +16 -0
  112. package/lib/module/useLocale.js.map +1 -0
  113. package/lib/module/useScrollToTop.js +8 -6
  114. package/lib/module/useScrollToTop.js.map +1 -1
  115. package/lib/module/useThenable.js +2 -1
  116. package/lib/module/useThenable.js.map +1 -1
  117. package/lib/module/useUnhandledLinking.js +69 -0
  118. package/lib/module/useUnhandledLinking.js.map +1 -0
  119. package/lib/typescript/src/Link.d.ts +3 -3
  120. package/lib/typescript/src/Link.d.ts.map +1 -1
  121. package/lib/typescript/src/LinkingContext.d.ts +2 -3
  122. package/lib/typescript/src/LinkingContext.d.ts.map +1 -1
  123. package/lib/typescript/src/LocaleDirContext.d.ts +4 -0
  124. package/lib/typescript/src/LocaleDirContext.d.ts.map +1 -0
  125. package/lib/typescript/src/NavigationContainer.d.ts +6 -6
  126. package/lib/typescript/src/NavigationContainer.d.ts.map +1 -1
  127. package/lib/typescript/src/ServerContainer.d.ts +2 -3
  128. package/lib/typescript/src/ServerContainer.d.ts.map +1 -1
  129. package/lib/typescript/src/ServerContext.d.ts +1 -2
  130. package/lib/typescript/src/ServerContext.d.ts.map +1 -1
  131. package/lib/typescript/src/UnhandledLinkingContext.d.ts +6 -0
  132. package/lib/typescript/src/UnhandledLinkingContext.d.ts.map +1 -0
  133. package/lib/typescript/src/__stubs__/createStackNavigator.d.ts +32 -0
  134. package/lib/typescript/src/__stubs__/createStackNavigator.d.ts.map +1 -0
  135. package/lib/typescript/src/{__mocks__ → __stubs__}/window.d.ts +2 -3
  136. package/lib/typescript/src/__stubs__/window.d.ts.map +1 -0
  137. package/lib/typescript/src/createMemoryHistory.d.ts +1 -1
  138. package/lib/typescript/src/createMemoryHistory.d.ts.map +1 -1
  139. package/lib/typescript/src/createStaticNavigation.d.ts +3 -3
  140. package/lib/typescript/src/createStaticNavigation.d.ts.map +1 -1
  141. package/lib/typescript/src/extractPathFromURL.d.ts +1 -1
  142. package/lib/typescript/src/extractPathFromURL.d.ts.map +1 -1
  143. package/lib/typescript/src/index.d.ts +12 -12
  144. package/lib/typescript/src/index.d.ts.map +1 -1
  145. package/lib/typescript/src/theming/DarkTheme.d.ts +1 -2
  146. package/lib/typescript/src/theming/DarkTheme.d.ts.map +1 -1
  147. package/lib/typescript/src/theming/DefaultTheme.d.ts +1 -2
  148. package/lib/typescript/src/theming/DefaultTheme.d.ts.map +1 -1
  149. package/lib/typescript/src/theming/fonts.d.ts +53 -0
  150. package/lib/typescript/src/theming/fonts.d.ts.map +1 -0
  151. package/lib/typescript/src/types.d.ts +41 -11
  152. package/lib/typescript/src/types.d.ts.map +1 -1
  153. package/lib/typescript/src/useBackButton.d.ts +2 -2
  154. package/lib/typescript/src/useBackButton.d.ts.map +1 -1
  155. package/lib/typescript/src/useBackButton.native.d.ts +4 -0
  156. package/lib/typescript/src/useBackButton.native.d.ts.map +1 -0
  157. package/lib/typescript/src/useDocumentTitle.d.ts +1 -1
  158. package/lib/typescript/src/useDocumentTitle.d.ts.map +1 -1
  159. package/lib/typescript/src/useDocumentTitle.native.d.ts +1 -1
  160. package/lib/typescript/src/useDocumentTitle.native.d.ts.map +1 -1
  161. package/lib/typescript/src/useLinkBuilder.d.ts +25 -0
  162. package/lib/typescript/src/useLinkBuilder.d.ts.map +1 -0
  163. package/lib/typescript/src/useLinkProps.d.ts +3 -3
  164. package/lib/typescript/src/useLinkProps.d.ts.map +1 -1
  165. package/lib/typescript/src/useLinkTo.d.ts +6 -0
  166. package/lib/typescript/src/useLinkTo.d.ts.map +1 -0
  167. package/lib/typescript/src/useLinking.d.ts +8 -20
  168. package/lib/typescript/src/useLinking.d.ts.map +1 -1
  169. package/lib/typescript/src/useLinking.native.d.ts +4 -20
  170. package/lib/typescript/src/useLinking.native.d.ts.map +1 -1
  171. package/lib/typescript/src/useLocale.d.ts +7 -0
  172. package/lib/typescript/src/useLocale.d.ts.map +1 -0
  173. package/lib/typescript/src/useScrollToTop.d.ts +1 -1
  174. package/lib/typescript/src/useScrollToTop.d.ts.map +1 -1
  175. package/lib/typescript/src/useThenable.d.ts +1 -1
  176. package/lib/typescript/src/useThenable.d.ts.map +1 -1
  177. package/lib/typescript/src/useUnhandledLinking.d.ts +7 -0
  178. package/lib/typescript/src/useUnhandledLinking.d.ts.map +1 -0
  179. package/package.json +15 -15
  180. package/src/Link.tsx +12 -3
  181. package/src/LinkingContext.tsx +9 -5
  182. package/src/LocaleDirContext.tsx +7 -0
  183. package/src/NavigationContainer.tsx +90 -36
  184. package/src/ServerContainer.tsx +2 -2
  185. package/src/ServerContext.tsx +1 -3
  186. package/src/UnhandledLinkingContext.tsx +18 -0
  187. package/src/{__mocks__ → __stubs__}/createStackNavigator.tsx +1 -3
  188. package/src/{__mocks__ → __stubs__}/window.tsx +8 -8
  189. package/src/createMemoryHistory.tsx +1 -1
  190. package/src/createStaticNavigation.tsx +8 -8
  191. package/src/extractPathFromURL.tsx +5 -2
  192. package/src/index.tsx +12 -12
  193. package/src/theming/DarkTheme.tsx +3 -3
  194. package/src/theming/DefaultTheme.tsx +3 -3
  195. package/src/theming/fonts.tsx +63 -0
  196. package/src/types.tsx +55 -11
  197. package/src/useBackButton.native.tsx +33 -0
  198. package/src/useBackButton.tsx +4 -26
  199. package/src/useDocumentTitle.native.tsx +1 -1
  200. package/src/useDocumentTitle.tsx +1 -1
  201. package/src/{useLinkTools.tsx → useLinkBuilder.tsx} +9 -9
  202. package/src/useLinkProps.tsx +27 -23
  203. package/src/useLinkTo.tsx +30 -0
  204. package/src/useLinking.native.tsx +28 -22
  205. package/src/useLinking.tsx +46 -44
  206. package/src/useLocale.tsx +18 -0
  207. package/src/useScrollToTop.tsx +14 -10
  208. package/src/useThenable.tsx +2 -1
  209. package/src/useUnhandledLinking.tsx +91 -0
  210. package/lib/commonjs/theming/ThemeContext.js +0 -16
  211. package/lib/commonjs/theming/ThemeContext.js.map +0 -1
  212. package/lib/commonjs/theming/ThemeProvider.js +0 -21
  213. package/lib/commonjs/theming/ThemeProvider.js.map +0 -1
  214. package/lib/commonjs/theming/useTheme.js +0 -16
  215. package/lib/commonjs/theming/useTheme.js.map +0 -1
  216. package/lib/commonjs/useLinkTools.js +0 -81
  217. package/lib/commonjs/useLinkTools.js.map +0 -1
  218. package/lib/module/theming/ThemeContext.js +0 -6
  219. package/lib/module/theming/ThemeContext.js.map +0 -1
  220. package/lib/module/theming/ThemeProvider.js +0 -12
  221. package/lib/module/theming/ThemeProvider.js.map +0 -1
  222. package/lib/module/theming/useTheme.js +0 -7
  223. package/lib/module/theming/useTheme.js.map +0 -1
  224. package/lib/module/useLinkTools.js.map +0 -1
  225. package/lib/typescript/src/__mocks__/createStackNavigator.d.ts +0 -57
  226. package/lib/typescript/src/__mocks__/createStackNavigator.d.ts.map +0 -1
  227. package/lib/typescript/src/__mocks__/window.d.ts.map +0 -1
  228. package/lib/typescript/src/theming/ThemeContext.d.ts +0 -5
  229. package/lib/typescript/src/theming/ThemeContext.d.ts.map +0 -1
  230. package/lib/typescript/src/theming/ThemeProvider.d.ts +0 -9
  231. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +0 -1
  232. package/lib/typescript/src/theming/useTheme.d.ts +0 -2
  233. package/lib/typescript/src/theming/useTheme.d.ts.map +0 -1
  234. package/lib/typescript/src/useLinkTools.d.ts +0 -33
  235. package/lib/typescript/src/useLinkTools.d.ts.map +0 -1
  236. package/src/theming/ThemeContext.tsx +0 -10
  237. package/src/theming/ThemeProvider.tsx +0 -15
  238. package/src/theming/useTheme.tsx +0 -9
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createComponentForStaticNavigation,
3
3
  createPathConfigForStaticNavigation,
4
- ParamListBase,
5
- StaticNavigation,
4
+ type ParamListBase,
5
+ type StaticNavigation,
6
6
  } from '@react-navigation/core';
7
7
  import * as React from 'react';
8
8
 
9
- import NavigationContainer from './NavigationContainer';
9
+ import { NavigationContainer } from './NavigationContainer';
10
10
  import type { LinkingOptions } from './types';
11
11
 
12
12
  type Props = Omit<
@@ -26,9 +26,7 @@ type Props = Omit<
26
26
  * @param tree Static navigation config.
27
27
  * @returns Navigation component to use in your app.
28
28
  */
29
- export default function createStaticNavigation(
30
- tree: StaticNavigation<any, any, any>
31
- ) {
29
+ export function createStaticNavigation(tree: StaticNavigation<any, any, any>) {
32
30
  const Component = createComponentForStaticNavigation(tree, 'RootNavigator');
33
31
  const linkingConfig = {
34
32
  screens: tree.config.screens
@@ -36,7 +34,7 @@ export default function createStaticNavigation(
36
34
  : {},
37
35
  };
38
36
 
39
- return function Navigation({ linking, ...rest }: Props) {
37
+ function Navigation({ linking, ...rest }: Props) {
40
38
  return (
41
39
  <NavigationContainer
42
40
  {...rest}
@@ -45,5 +43,7 @@ export default function createStaticNavigation(
45
43
  <Component />
46
44
  </NavigationContainer>
47
45
  );
48
- };
46
+ }
47
+
48
+ return React.forwardRef(Navigation);
49
49
  }
@@ -1,6 +1,6 @@
1
1
  import escapeStringRegexp from 'escape-string-regexp';
2
2
 
3
- export default function extractPathFromURL(prefixes: string[], url: string) {
3
+ export function extractPathFromURL(prefixes: string[], url: string) {
4
4
  for (const prefix of prefixes) {
5
5
  const protocol = prefix.match(/^[^:]+:/)?.[0] ?? '';
6
6
  const host = prefix
@@ -15,7 +15,10 @@ export default function extractPathFromURL(prefixes: string[], url: string) {
15
15
  .join('\\.')}`
16
16
  );
17
17
 
18
- const normalizedURL = url.replace(/\/+/g, '/');
18
+ const [originAndPath, searchParams] = url.split('?');
19
+ const normalizedURL = originAndPath
20
+ .replace(/\/+/g, '/')
21
+ .concat(searchParams ? `?${searchParams}` : '');
19
22
 
20
23
  if (prefixRegex.test(normalizedURL)) {
21
24
  return normalizedURL.replace(prefixRegex, '');
package/src/index.tsx CHANGED
@@ -1,14 +1,14 @@
1
- export { default as createStaticNavigation } from './createStaticNavigation';
2
- export { default as Link } from './Link';
3
- export { default as LinkingContext } from './LinkingContext';
4
- export { default as NavigationContainer } from './NavigationContainer';
5
- export { default as ServerContainer } from './ServerContainer';
6
- export { default as DarkTheme } from './theming/DarkTheme';
7
- export { default as DefaultTheme } from './theming/DefaultTheme';
8
- export { default as ThemeProvider } from './theming/ThemeProvider';
9
- export { default as useTheme } from './theming/useTheme';
1
+ export { createStaticNavigation } from './createStaticNavigation';
2
+ export { Link } from './Link';
3
+ export { LinkingContext } from './LinkingContext';
4
+ export { NavigationContainer } from './NavigationContainer';
5
+ export { ServerContainer } from './ServerContainer';
6
+ export { DarkTheme } from './theming/DarkTheme';
7
+ export { DefaultTheme } from './theming/DefaultTheme';
10
8
  export * from './types';
11
- export { default as useLinkProps } from './useLinkProps';
12
- export { default as useLinkTools } from './useLinkTools';
13
- export { default as useScrollToTop } from './useScrollToTop';
9
+ export { useLinkBuilder } from './useLinkBuilder';
10
+ export { useLinkProps } from './useLinkProps';
11
+ export { useLocale } from './useLocale';
12
+ export { useScrollToTop } from './useScrollToTop';
13
+ export { UNSTABLE_useUnhandledLinking } from './useUnhandledLinking';
14
14
  export * from '@react-navigation/core';
@@ -1,6 +1,7 @@
1
1
  import type { Theme } from '../types';
2
+ import { fonts } from './fonts';
2
3
 
3
- const DarkTheme: Theme = {
4
+ export const DarkTheme: Theme = {
4
5
  dark: true,
5
6
  colors: {
6
7
  primary: 'rgb(10, 132, 255)',
@@ -10,6 +11,5 @@ const DarkTheme: Theme = {
10
11
  border: 'rgb(39, 39, 41)',
11
12
  notification: 'rgb(255, 69, 58)',
12
13
  },
14
+ fonts,
13
15
  };
14
-
15
- export default DarkTheme;
@@ -1,6 +1,7 @@
1
1
  import type { Theme } from '../types';
2
+ import { fonts } from './fonts';
2
3
 
3
- const DefaultTheme: Theme = {
4
+ export const DefaultTheme: Theme = {
4
5
  dark: false,
5
6
  colors: {
6
7
  primary: 'rgb(0, 122, 255)',
@@ -10,6 +11,5 @@ const DefaultTheme: Theme = {
10
11
  border: 'rgb(216, 216, 216)',
11
12
  notification: 'rgb(255, 59, 48)',
12
13
  },
14
+ fonts,
13
15
  };
14
-
15
- export default DefaultTheme;
@@ -0,0 +1,63 @@
1
+ import { Platform } from 'react-native';
2
+
3
+ import type { Theme } from '../types';
4
+
5
+ const WEB_FONT_STACK =
6
+ 'system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"';
7
+
8
+ export const fonts = Platform.select({
9
+ web: {
10
+ regular: {
11
+ fontFamily: WEB_FONT_STACK,
12
+ fontWeight: '400',
13
+ },
14
+ medium: {
15
+ fontFamily: WEB_FONT_STACK,
16
+ fontWeight: '500',
17
+ },
18
+ bold: {
19
+ fontFamily: WEB_FONT_STACK,
20
+ fontWeight: '600',
21
+ },
22
+ heavy: {
23
+ fontFamily: WEB_FONT_STACK,
24
+ fontWeight: '700',
25
+ },
26
+ },
27
+ ios: {
28
+ regular: {
29
+ fontFamily: 'System',
30
+ fontWeight: '400',
31
+ },
32
+ medium: {
33
+ fontFamily: 'System',
34
+ fontWeight: '500',
35
+ },
36
+ bold: {
37
+ fontFamily: 'System',
38
+ fontWeight: '600',
39
+ },
40
+ heavy: {
41
+ fontFamily: 'System',
42
+ fontWeight: '700',
43
+ },
44
+ },
45
+ default: {
46
+ regular: {
47
+ fontFamily: 'sans-serif',
48
+ fontWeight: 'normal',
49
+ },
50
+ medium: {
51
+ fontFamily: 'sans-serif-medium',
52
+ fontWeight: 'normal',
53
+ },
54
+ bold: {
55
+ fontFamily: 'sans-serif',
56
+ fontWeight: '600',
57
+ },
58
+ heavy: {
59
+ fontFamily: 'sans-serif',
60
+ fontWeight: '700',
61
+ },
62
+ },
63
+ } as const satisfies Record<string, Theme['fonts']>);
package/src/types.tsx CHANGED
@@ -6,18 +6,49 @@ import type {
6
6
  Route,
7
7
  } from '@react-navigation/core';
8
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
- };
9
+ declare global {
10
+ // eslint-disable-next-line @typescript-eslint/no-namespace
11
+ namespace ReactNavigation {
12
+ interface Theme {
13
+ dark: boolean;
14
+ colors: {
15
+ primary: string;
16
+ background: string;
17
+ card: string;
18
+ text: string;
19
+ border: string;
20
+ notification: string;
21
+ };
22
+ fonts: {
23
+ regular: FontStyle;
24
+ medium: FontStyle;
25
+ bold: FontStyle;
26
+ heavy: FontStyle;
27
+ };
28
+ }
29
+ }
30
+ }
31
+
32
+ export type LocaleDirection = 'ltr' | 'rtl';
33
+
34
+ type FontStyle = {
35
+ fontFamily: string;
36
+ fontWeight:
37
+ | 'normal'
38
+ | 'bold'
39
+ | '100'
40
+ | '200'
41
+ | '300'
42
+ | '400'
43
+ | '500'
44
+ | '600'
45
+ | '700'
46
+ | '800'
47
+ | '900';
19
48
  };
20
49
 
50
+ export type Theme = ReactNavigation.Theme;
51
+
21
52
  export type LinkingOptions<ParamList extends {}> = {
22
53
  /**
23
54
  * Whether deep link handling should be enabled.
@@ -74,8 +105,21 @@ export type LinkingOptions<ParamList extends {}> = {
74
105
  * ```
75
106
  */
76
107
  config?: {
77
- initialRouteName?: keyof ParamList;
108
+ /**
109
+ * Path string to match against for the whole navigation tree.
110
+ * It's not possible to specify params here since this doesn't belong to a screen.
111
+ * This is useful when the whole app is under a specific path.
112
+ * e.g. all of the screens are under `/admin` in `https://example.com/admin`
113
+ */
114
+ path?: string;
115
+ /**
116
+ * Path configuration for child screens.
117
+ */
78
118
  screens: PathConfigMap<ParamList>;
119
+ /**
120
+ * Name of the initial route to use for the root navigator.
121
+ */
122
+ initialRouteName?: keyof ParamList;
79
123
  };
80
124
  /**
81
125
  * Custom function to get the initial URL used for linking.
@@ -0,0 +1,33 @@
1
+ import type {
2
+ NavigationContainerRef,
3
+ ParamListBase,
4
+ } from '@react-navigation/core';
5
+ import * as React from 'react';
6
+ import { BackHandler } from 'react-native';
7
+
8
+ export 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
+ }
@@ -2,32 +2,10 @@ import type {
2
2
  NavigationContainerRef,
3
3
  ParamListBase,
4
4
  } from '@react-navigation/core';
5
- import * as React from 'react';
6
- import { BackHandler } from 'react-native';
7
5
 
8
- export default function useBackButton(
9
- ref: React.RefObject<NavigationContainerRef<ParamListBase>>
6
+ export function useBackButton(
7
+ _: React.RefObject<NavigationContainerRef<ParamListBase>>
10
8
  ) {
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]);
9
+ // No-op
10
+ // BackHandler is not available on web
33
11
  }
@@ -1,3 +1,3 @@
1
- export default function useDocumentTitle() {
1
+ export function useDocumentTitle() {
2
2
  // Noop for React Native
3
3
  }
@@ -9,7 +9,7 @@ import type { DocumentTitleOptions } from './types';
9
9
  /**
10
10
  * Set the document title for the active screen
11
11
  */
12
- export default function useDocumentTitle(
12
+ export function useDocumentTitle(
13
13
  ref: React.RefObject<NavigationContainerRef<ParamListBase>>,
14
14
  {
15
15
  enabled = true,
@@ -3,14 +3,14 @@ import {
3
3
  getActionFromState,
4
4
  getPathFromState,
5
5
  getStateFromPath,
6
- NavigationHelpers,
6
+ type NavigationHelpers,
7
7
  NavigationHelpersContext,
8
- NavigationProp,
9
- ParamListBase,
8
+ type NavigationProp,
9
+ type ParamListBase,
10
10
  } from '@react-navigation/core';
11
11
  import * as React from 'react';
12
12
 
13
- import LinkingContext from './LinkingContext';
13
+ import { LinkingContext } from './LinkingContext';
14
14
 
15
15
  type NavigationObject =
16
16
  | NavigationHelpers<ParamListBase>
@@ -45,10 +45,10 @@ const getRootStateForNavigate = (
45
45
  };
46
46
 
47
47
  /**
48
- * Build destination link for a navigate action.
49
- * Useful for showing anchor tags on the web for buttons that perform navigation.
48
+ * Helpers to build href or action based on the linking options.
49
+ * @returns `buildHref` to build an `href` for screen and `buildAction` to build an action from an `href`.
50
50
  */
51
- export default function useLinkTools() {
51
+ export function useLinkBuilder() {
52
52
  const navigation = React.useContext(NavigationHelpersContext);
53
53
  const linking = React.useContext(LinkingContext);
54
54
 
@@ -84,7 +84,7 @@ export default function useLinkTools() {
84
84
  const buildAction = React.useCallback(
85
85
  (href: string) => {
86
86
  if (!href.startsWith('/')) {
87
- throw new Error(`The path must start with '/' (${href}).`);
87
+ throw new Error(`The href must start with '/' (${href}).`);
88
88
  }
89
89
 
90
90
  const { options } = linking;
@@ -98,7 +98,7 @@ export default function useLinkTools() {
98
98
 
99
99
  return action ?? CommonActions.reset(state);
100
100
  } else {
101
- throw new Error('Failed to parse the path to a navigation state.');
101
+ throw new Error('Failed to parse the href to a navigation state.');
102
102
  }
103
103
  },
104
104
  [linking]
@@ -1,20 +1,20 @@
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 '@react-navigation/core';
9
9
  import type { NavigationState, PartialState } from '@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';
13
+ import { LinkingContext } from './LinkingContext';
14
14
 
15
15
  export type Props<
16
16
  ParamList extends ReactNavigation.RootParamList,
17
- RouteName extends keyof ParamList = keyof ParamList
17
+ RouteName extends keyof ParamList = keyof ParamList,
18
18
  > =
19
19
  | ({
20
20
  screen: Extract<RouteName, string>;
@@ -43,7 +43,7 @@ const getStateFromParams = (
43
43
  {
44
44
  name: params.screen,
45
45
  params: params.params,
46
- // @ts-expect-error
46
+ // @ts-expect-error this is fine 🔥
47
47
  state: params.screen
48
48
  ? getStateFromParams(
49
49
  params.params as
@@ -67,9 +67,12 @@ const getStateFromParams = (
67
67
  * @param props.href Optional absolute path to use for the href (e.g. `/feeds/hot`).
68
68
  * @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
69
69
  */
70
- export default function useLinkProps<
71
- ParamList extends ReactNavigation.RootParamList
72
- >({ screen, params, href, action }: Props<ParamList>) {
70
+ export function useLinkProps<ParamList extends ReactNavigation.RootParamList>({
71
+ screen,
72
+ params,
73
+ href,
74
+ action,
75
+ }: Props<ParamList>) {
73
76
  const root = React.useContext(NavigationContainerRefContext);
74
77
  const navigation = React.useContext(NavigationHelpersContext);
75
78
  const { options } = React.useContext(LinkingContext);
@@ -77,19 +80,20 @@ export default function useLinkProps<
77
80
  const onPress = (
78
81
  e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
79
82
  ) => {
83
+ // @ts-expect-error: these properties exist on web, but not in React Native
84
+ const hasModifierKey = e.metaKey || e.altKey || e.ctrlKey || e.shiftKey; // ignore clicks with modifier keys
85
+ // @ts-expect-error: these properties exist on web, but not in React Native
86
+ const isLeftClick = e.button == null || e.button === 0; // only handle left clicks
87
+ const isSelfTarget = [undefined, null, '', 'self'].includes(
88
+ // @ts-expect-error: these properties exist on web, but not in React Native
89
+ e.currentTarget?.target
90
+ ); // let browser handle "target=_blank" etc.
91
+
80
92
  let shouldHandle = false;
81
93
 
82
94
  if (Platform.OS !== 'web' || !e) {
83
- shouldHandle = e ? !e.defaultPrevented : true;
84
- } else if (
85
- !e.defaultPrevented && // onPress prevented default
86
- // @ts-expect-error: these properties exist on web, but not in React Native
87
- !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
88
- // @ts-expect-error: these properties exist on web, but not in React Native
89
- (e.button == null || e.button === 0) && // ignore everything but left clicks
90
- // @ts-expect-error: these properties exist on web, but not in React Native
91
- [undefined, null, '', 'self'].includes(e.currentTarget?.target) // let browser handle "target=_blank" etc.
92
- ) {
95
+ shouldHandle = true;
96
+ } else if (!hasModifierKey && isLeftClick && isSelfTarget) {
93
97
  e.preventDefault();
94
98
  shouldHandle = true;
95
99
  }
@@ -106,7 +110,7 @@ export default function useLinkProps<
106
110
  );
107
111
  }
108
112
  } else {
109
- // @ts-expect-error: This is already type-checked by the prop types
113
+ // @ts-expect-error This is already type-checked by the prop types
110
114
  navigation?.navigate(screen, params);
111
115
  }
112
116
  }
@@ -123,9 +127,9 @@ export default function useLinkProps<
123
127
  routes: [
124
128
  {
125
129
  name: screen,
126
- // @ts-expect-error
130
+ // @ts-expect-error this is fine 🔥
127
131
  params: params,
128
- // @ts-expect-error
132
+ // @ts-expect-error this is fine 🔥
129
133
  state: getStateFromParams(params),
130
134
  },
131
135
  ],
@@ -0,0 +1,30 @@
1
+ import { NavigationContainerRefContext } from '@react-navigation/core';
2
+ import * as React from 'react';
3
+
4
+ import { useLinkBuilder } from './useLinkBuilder';
5
+
6
+ /**
7
+ * Helper to navigate to a screen using a href based on the linking options.
8
+ * @returns function that receives the href to navigate to.
9
+ */
10
+ export function useLinkTo() {
11
+ const navigation = React.useContext(NavigationContainerRefContext);
12
+ const { buildAction } = useLinkBuilder();
13
+
14
+ const linkTo = React.useCallback(
15
+ (href: string) => {
16
+ if (navigation === undefined) {
17
+ throw new Error(
18
+ "Couldn't find a navigation object. Is your component inside NavigationContainer?"
19
+ );
20
+ }
21
+
22
+ const action = buildAction(href);
23
+
24
+ navigation.dispatch(action);
25
+ },
26
+ [buildAction, navigation]
27
+ );
28
+
29
+ return linkTo;
30
+ }
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  getActionFromState as getActionFromStateDefault,
3
3
  getStateFromPath as getStateFromPathDefault,
4
- NavigationContainerRef,
5
- ParamListBase,
4
+ type NavigationContainerRef,
5
+ type ParamListBase,
6
6
  useNavigationIndependentTree,
7
7
  } from '@react-navigation/core';
8
8
  import * as React from 'react';
9
9
  import { Linking, Platform } from 'react-native';
10
10
 
11
- import extractPathFromURL from './extractPathFromURL';
11
+ import { extractPathFromURL } from './extractPathFromURL';
12
12
  import type { LinkingOptions } from './types';
13
13
 
14
14
  type ResultState = ReturnType<typeof getStateFromPathDefault>;
15
15
 
16
16
  type Options = LinkingOptions<ParamListBase>;
17
17
 
18
- let linkingHandlers: Symbol[] = [];
18
+ const linkingHandlers: symbol[] = [];
19
19
 
20
- export default function useLinking(
20
+ export function useLinking(
21
21
  ref: React.RefObject<NavigationContainerRef<ParamListBase>>,
22
22
  {
23
23
  enabled = true,
@@ -27,11 +27,11 @@ export default function useLinking(
27
27
  getInitialURL = () =>
28
28
  Promise.race([
29
29
  Linking.getInitialURL(),
30
- new Promise<undefined>((resolve) =>
30
+ new Promise<undefined>((resolve) => {
31
31
  // Timeout in 150ms if `getInitialState` doesn't resolve
32
32
  // Workaround for https://github.com/facebook/react-native/issues/25675
33
- setTimeout(resolve, 150)
34
- ),
33
+ setTimeout(resolve, 150);
34
+ }),
35
35
  ]),
36
36
  subscribe = (listener) => {
37
37
  const callback = ({ url }: { url: string }) => listener(url);
@@ -55,7 +55,8 @@ export default function useLinking(
55
55
  },
56
56
  getStateFromPath = getStateFromPathDefault,
57
57
  getActionFromState = getActionFromStateDefault,
58
- }: Options
58
+ }: Options,
59
+ onUnhandledLinking: (lastUnhandledLining: string | undefined) => void
59
60
  ) {
60
61
  const independent = useNavigationIndependentTree();
61
62
 
@@ -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 && typeof url !== 'string') {
144
- return url.then((url) => {
145
- const state = getStateFromURL(url);
144
+ if (url != null) {
145
+ if (typeof url !== 'string') {
146
+ return url.then((url) => {
147
+ const state = getStateFromURL(url);
146
148
 
147
- return state;
148
- });
149
+ if (typeof url === 'string') {
150
+ // If the link were handled, it gets cleared in NavigationContainer
151
+ onUnhandledLinking(extractPathFromURL(prefixes, url));
152
+ }
153
+
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,14 +183,10 @@ export default function useLinking(
173
183
  const state = navigation ? getStateFromURL(url) : undefined;
174
184
 
175
185
  if (navigation && state) {
176
- // Make sure that the routes in the state exist in the root navigator
177
- // Otherwise there's an error in the linking configuration
186
+ // If the link were handled, it gets cleared in NavigationContainer
187
+ onUnhandledLinking(extractPathFromURL(prefixes, url));
178
188
  const rootState = navigation.getRootState();
179
-
180
189
  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
190
  return;
185
191
  }
186
192
 
@@ -207,7 +213,7 @@ export default function useLinking(
207
213
  };
208
214
 
209
215
  return subscribe(listener);
210
- }, [enabled, getStateFromURL, ref, subscribe]);
216
+ }, [enabled, getStateFromURL, onUnhandledLinking, prefixes, ref, subscribe]);
211
217
 
212
218
  return {
213
219
  getInitialState,