@react-navigation/native 8.0.0-alpha.0 → 8.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 (128) hide show
  1. package/ReactNavigation.podspec +20 -0
  2. package/android/build.gradle +147 -0
  3. package/android/src/main/AndroidManifest.xml +2 -0
  4. package/android/src/main/java/org/reactnavigation/MaterialSymbolModule.kt +100 -0
  5. package/android/src/main/java/org/reactnavigation/MaterialSymbolTypeface.kt +77 -0
  6. package/android/src/main/java/org/reactnavigation/MaterialSymbolView.kt +95 -0
  7. package/android/src/main/java/org/reactnavigation/MaterialSymbolViewManager.kt +49 -0
  8. package/android/src/main/java/org/reactnavigation/ReactNavigationPackage.kt +34 -0
  9. package/assets/fonts/MaterialSymbolsOutlined.codepoints +4102 -0
  10. package/assets/fonts/MaterialSymbolsOutlined_100.ttf +0 -0
  11. package/assets/fonts/MaterialSymbolsOutlined_200.ttf +0 -0
  12. package/assets/fonts/MaterialSymbolsOutlined_300.ttf +0 -0
  13. package/assets/fonts/MaterialSymbolsOutlined_400.ttf +0 -0
  14. package/assets/fonts/MaterialSymbolsOutlined_500.ttf +0 -0
  15. package/assets/fonts/MaterialSymbolsOutlined_600.ttf +0 -0
  16. package/assets/fonts/MaterialSymbolsOutlined_700.ttf +0 -0
  17. package/assets/fonts/MaterialSymbolsRounded.codepoints +4102 -0
  18. package/assets/fonts/MaterialSymbolsRounded_100.ttf +0 -0
  19. package/assets/fonts/MaterialSymbolsRounded_200.ttf +0 -0
  20. package/assets/fonts/MaterialSymbolsRounded_300.ttf +0 -0
  21. package/assets/fonts/MaterialSymbolsRounded_400.ttf +0 -0
  22. package/assets/fonts/MaterialSymbolsRounded_500.ttf +0 -0
  23. package/assets/fonts/MaterialSymbolsRounded_600.ttf +0 -0
  24. package/assets/fonts/MaterialSymbolsRounded_700.ttf +0 -0
  25. package/assets/fonts/MaterialSymbolsSharp.codepoints +4102 -0
  26. package/assets/fonts/MaterialSymbolsSharp_100.ttf +0 -0
  27. package/assets/fonts/MaterialSymbolsSharp_200.ttf +0 -0
  28. package/assets/fonts/MaterialSymbolsSharp_300.ttf +0 -0
  29. package/assets/fonts/MaterialSymbolsSharp_400.ttf +0 -0
  30. package/assets/fonts/MaterialSymbolsSharp_500.ttf +0 -0
  31. package/assets/fonts/MaterialSymbolsSharp_600.ttf +0 -0
  32. package/assets/fonts/MaterialSymbolsSharp_700.ttf +0 -0
  33. package/ios/ReactNavigationSFSymbolView.h +14 -0
  34. package/ios/ReactNavigationSFSymbolView.mm +79 -0
  35. package/ios/ReactNavigationSFSymbolView.swift +300 -0
  36. package/lib/module/NavigationContainer.js +7 -2
  37. package/lib/module/NavigationContainer.js.map +1 -1
  38. package/lib/module/createStaticNavigation.js +3 -6
  39. package/lib/module/createStaticNavigation.js.map +1 -1
  40. package/lib/module/index.js +4 -1
  41. package/lib/module/index.js.map +1 -1
  42. package/lib/module/native/MaterialSymbol.android.js +58 -0
  43. package/lib/module/native/MaterialSymbol.android.js.map +1 -0
  44. package/lib/module/native/MaterialSymbol.js +9 -0
  45. package/lib/module/native/MaterialSymbol.js.map +1 -0
  46. package/lib/module/native/MaterialSymbolData.js +2 -0
  47. package/lib/module/native/MaterialSymbolData.js.map +1 -0
  48. package/lib/module/native/MaterialSymbolViewNativeComponent.ts +23 -0
  49. package/lib/module/native/NativeMaterialSymbolModule.js +7 -0
  50. package/lib/module/native/NativeMaterialSymbolModule.js.map +1 -0
  51. package/lib/module/native/SFSymbol.ios.js +46 -0
  52. package/lib/module/native/SFSymbol.ios.js.map +1 -0
  53. package/lib/module/native/SFSymbol.js +6 -0
  54. package/lib/module/native/SFSymbol.js.map +1 -0
  55. package/lib/module/native/SFSymbolViewNativeComponent.ts +32 -0
  56. package/lib/module/native/constants.js +14 -0
  57. package/lib/module/native/constants.js.map +1 -0
  58. package/lib/module/native/types.js +4 -0
  59. package/lib/module/native/types.js.map +1 -0
  60. package/lib/module/theming/{DefaultTheme.js → LightTheme.js} +2 -2
  61. package/lib/module/theming/LightTheme.js.map +1 -0
  62. package/lib/module/theming/MaterialTheme.android.js +29 -0
  63. package/lib/module/theming/MaterialTheme.android.js.map +1 -0
  64. package/lib/module/theming/MaterialTheme.js +18 -0
  65. package/lib/module/theming/MaterialTheme.js.map +1 -0
  66. package/lib/module/useLinkBuilder.js +24 -5
  67. package/lib/module/useLinkBuilder.js.map +1 -1
  68. package/lib/module/useLinkTo.js +2 -4
  69. package/lib/module/useLinkTo.js.map +1 -1
  70. package/lib/module/useLinking.native.js +20 -3
  71. package/lib/module/useLinking.native.js.map +1 -1
  72. package/lib/typescript/src/NavigationContainer.d.ts +6 -1
  73. package/lib/typescript/src/NavigationContainer.d.ts.map +1 -1
  74. package/lib/typescript/src/createStaticNavigation.d.ts +3 -3
  75. package/lib/typescript/src/createStaticNavigation.d.ts.map +1 -1
  76. package/lib/typescript/src/index.d.ts +4 -1
  77. package/lib/typescript/src/index.d.ts.map +1 -1
  78. package/lib/typescript/src/native/MaterialSymbol.android.d.ts +8 -0
  79. package/lib/typescript/src/native/MaterialSymbol.android.d.ts.map +1 -0
  80. package/lib/typescript/src/native/MaterialSymbol.d.ts +8 -0
  81. package/lib/typescript/src/native/MaterialSymbol.d.ts.map +1 -0
  82. package/lib/typescript/src/native/MaterialSymbolData.d.ts +2 -0
  83. package/lib/typescript/src/native/MaterialSymbolData.d.ts.map +1 -0
  84. package/lib/typescript/src/native/MaterialSymbolViewNativeComponent.d.ts +11 -0
  85. package/lib/typescript/src/native/MaterialSymbolViewNativeComponent.d.ts.map +1 -0
  86. package/lib/typescript/src/native/NativeMaterialSymbolModule.d.ts +7 -0
  87. package/lib/typescript/src/native/NativeMaterialSymbolModule.d.ts.map +1 -0
  88. package/lib/typescript/src/native/SFSymbol.d.ts +5 -0
  89. package/lib/typescript/src/native/SFSymbol.d.ts.map +1 -0
  90. package/lib/typescript/src/native/SFSymbol.ios.d.ts +5 -0
  91. package/lib/typescript/src/native/SFSymbol.ios.d.ts.map +1 -0
  92. package/lib/typescript/src/native/SFSymbolViewNativeComponent.d.ts +23 -0
  93. package/lib/typescript/src/native/SFSymbolViewNativeComponent.d.ts.map +1 -0
  94. package/lib/typescript/src/native/constants.d.ts +12 -0
  95. package/lib/typescript/src/native/constants.d.ts.map +1 -0
  96. package/lib/typescript/src/native/types.d.ts +181 -0
  97. package/lib/typescript/src/native/types.d.ts.map +1 -0
  98. package/lib/typescript/src/theming/{DefaultTheme.d.ts → LightTheme.d.ts} +2 -2
  99. package/lib/typescript/src/theming/LightTheme.d.ts.map +1 -0
  100. package/lib/typescript/src/theming/MaterialTheme.android.d.ts +127 -0
  101. package/lib/typescript/src/theming/MaterialTheme.android.d.ts.map +1 -0
  102. package/lib/typescript/src/theming/MaterialTheme.d.ts +114 -0
  103. package/lib/typescript/src/theming/MaterialTheme.d.ts.map +1 -0
  104. package/lib/typescript/src/useLinkBuilder.d.ts +104 -6
  105. package/lib/typescript/src/useLinkBuilder.d.ts.map +1 -1
  106. package/lib/typescript/src/useLinking.native.d.ts.map +1 -1
  107. package/package.json +39 -4
  108. package/src/NavigationContainer.tsx +20 -3
  109. package/src/createStaticNavigation.tsx +8 -12
  110. package/src/index.tsx +7 -1
  111. package/src/native/MaterialSymbol.android.tsx +83 -0
  112. package/src/native/MaterialSymbol.tsx +17 -0
  113. package/src/native/MaterialSymbolData.tsx +4106 -0
  114. package/src/native/MaterialSymbolViewNativeComponent.ts +23 -0
  115. package/src/native/NativeMaterialSymbolModule.ts +19 -0
  116. package/src/native/SFSymbol.ios.tsx +53 -0
  117. package/src/native/SFSymbol.tsx +9 -0
  118. package/src/native/SFSymbolViewNativeComponent.ts +32 -0
  119. package/src/native/constants.tsx +11 -0
  120. package/src/native/types.tsx +218 -0
  121. package/src/theming/{DefaultTheme.tsx → LightTheme.tsx} +1 -1
  122. package/src/theming/MaterialTheme.android.tsx +30 -0
  123. package/src/theming/MaterialTheme.tsx +19 -0
  124. package/src/useLinkBuilder.tsx +26 -6
  125. package/src/useLinkTo.tsx +2 -2
  126. package/src/useLinking.native.tsx +38 -15
  127. package/lib/module/theming/DefaultTheme.js.map +0 -1
  128. package/lib/typescript/src/theming/DefaultTheme.d.ts.map +0 -1
@@ -0,0 +1,23 @@
1
+ /* eslint-disable import-x/no-default-export */
2
+
3
+ import {
4
+ codegenNativeComponent,
5
+ CodegenTypes,
6
+ type ColorValue,
7
+ type ViewProps,
8
+ } from 'react-native';
9
+
10
+ export interface NativeProps extends ViewProps {
11
+ name: string;
12
+ variant?: string;
13
+ weight?: CodegenTypes.WithDefault<
14
+ 0 | 100 | 200 | 300 | 400 | 500 | 600 | 700,
15
+ 0
16
+ >;
17
+ size: CodegenTypes.Float;
18
+ color?: ColorValue;
19
+ }
20
+
21
+ export default codegenNativeComponent<NativeProps>(
22
+ 'ReactNavigationMaterialSymbolView'
23
+ );
@@ -0,0 +1,19 @@
1
+ /* eslint-disable import-x/no-default-export */
2
+
3
+ import { type TurboModule, TurboModuleRegistry } from 'react-native';
4
+
5
+ export interface Spec extends TurboModule {
6
+ getImageSource(
7
+ name: string,
8
+ variant: string | undefined,
9
+ weight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | undefined,
10
+ size: number,
11
+ // Codegen requires using `Object` instead of `object
12
+ // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
13
+ color: Object
14
+ ): string;
15
+ }
16
+
17
+ export default TurboModuleRegistry.getEnforcing<Spec>(
18
+ 'ReactNavigationMaterialSymbolModule'
19
+ );
@@ -0,0 +1,53 @@
1
+ import type { ViewProps } from 'react-native';
2
+
3
+ import { FONT_WEIGHTS } from './constants';
4
+ import SFSymbolViewNativeComponent from './SFSymbolViewNativeComponent';
5
+ import type { SFSymbolOptions } from './types';
6
+
7
+ export type SFSymbolProps = SFSymbolOptions & ViewProps;
8
+
9
+ export function SFSymbol({
10
+ name,
11
+ size = 24,
12
+ color,
13
+ weight,
14
+ scale = 'medium',
15
+ mode = 'monochrome',
16
+ colors,
17
+ animation,
18
+ style,
19
+ ...rest
20
+ }: SFSymbolProps): React.ReactElement {
21
+ const animConfig =
22
+ typeof animation === 'string' ? { effect: animation } : animation;
23
+
24
+ return (
25
+ <SFSymbolViewNativeComponent
26
+ name={name}
27
+ size={size}
28
+ color={color}
29
+ weight={typeof weight === 'string' ? FONT_WEIGHTS[weight] : (weight ?? 0)}
30
+ scale={scale}
31
+ mode={mode}
32
+ colorPrimary={colors?.primary ?? color}
33
+ colorSecondary={colors?.secondary}
34
+ colorTertiary={colors?.tertiary}
35
+ animation={animConfig?.effect ?? ''}
36
+ animationRepeating={animConfig?.repeating ?? false}
37
+ animationRepeatCount={animConfig?.repeatCount ?? 0}
38
+ animationSpeed={animConfig?.speed ?? 1}
39
+ animationWholeSymbol={animConfig?.wholeSymbol ?? false}
40
+ animationDirection={animConfig?.direction ?? ''}
41
+ animationReversing={animConfig?.reversing ?? false}
42
+ animationCumulative={animConfig?.cumulative ?? false}
43
+ style={[
44
+ {
45
+ width: size,
46
+ height: size,
47
+ },
48
+ style,
49
+ ]}
50
+ {...rest}
51
+ />
52
+ );
53
+ }
@@ -0,0 +1,9 @@
1
+ import type { ViewProps } from 'react-native';
2
+
3
+ import type { SFSymbolOptions } from './types';
4
+
5
+ export type SFSymbolProps = SFSymbolOptions & ViewProps;
6
+
7
+ export function SFSymbol(_: SFSymbolProps): React.ReactElement {
8
+ throw new Error('SFSymbol is only supported on iOS.');
9
+ }
@@ -0,0 +1,32 @@
1
+ /* eslint-disable import-x/no-default-export */
2
+
3
+ import {
4
+ codegenNativeComponent,
5
+ CodegenTypes,
6
+ type ColorValue,
7
+ type ViewProps,
8
+ } from 'react-native';
9
+
10
+ export interface NativeProps extends ViewProps {
11
+ name: string;
12
+ size: CodegenTypes.Float;
13
+ color?: ColorValue;
14
+ weight: CodegenTypes.Int32;
15
+ scale: string;
16
+ mode: string;
17
+ colorPrimary?: ColorValue;
18
+ colorSecondary?: ColorValue;
19
+ colorTertiary?: ColorValue;
20
+ animation: string;
21
+ animationRepeating: boolean;
22
+ animationRepeatCount: CodegenTypes.Int32;
23
+ animationSpeed: CodegenTypes.Float;
24
+ animationWholeSymbol: boolean;
25
+ animationDirection: string;
26
+ animationReversing: boolean;
27
+ animationCumulative: boolean;
28
+ }
29
+
30
+ export default codegenNativeComponent<NativeProps>(
31
+ 'ReactNavigationSFSymbolView'
32
+ );
@@ -0,0 +1,11 @@
1
+ export const FONT_WEIGHTS = {
2
+ thin: 100,
3
+ ultralight: 200,
4
+ light: 300,
5
+ regular: 400,
6
+ medium: 500,
7
+ semibold: 600,
8
+ bold: 700,
9
+ extrabold: 800,
10
+ black: 900,
11
+ } as const;
@@ -0,0 +1,218 @@
1
+ import type { ColorValue } from 'react-native';
2
+
3
+ import type { FONT_WEIGHTS } from './constants';
4
+ import type { MaterialSymbolName } from './MaterialSymbolData';
5
+
6
+ export type MaterialSymbolOptions = {
7
+ /**
8
+ * The name of the Material Symbol to display.
9
+ */
10
+ name: MaterialSymbolName;
11
+ /**
12
+ * The variant of the symbol.
13
+ *
14
+ * Can be customized using `react-navigation` key in `package.json`:
15
+ *
16
+ * ```json
17
+ * "react-navigation": {
18
+ * "material-symbol": {
19
+ * "fonts": [
20
+ * {
21
+ * "variant": "rounded",
22
+ * "weight": 300,
23
+ * },
24
+ * ]
25
+ * }
26
+ * }
27
+ * ```
28
+ *
29
+ * Automatically set if a single variant is available.
30
+ *
31
+ * @default 'outlined'
32
+ */
33
+ variant?: 'outlined' | 'rounded' | 'sharp';
34
+ /**
35
+ * The weight of the symbol.
36
+ *
37
+ * Can be customized using `react-navigation` key in `package.json`:
38
+ *
39
+ * ```json
40
+ * "react-navigation": {
41
+ * "material-symbol": {
42
+ * "fonts": [
43
+ * {
44
+ * "variant": "rounded",
45
+ * "weight": 300,
46
+ * },
47
+ * ]
48
+ * }
49
+ * }
50
+ * ```
51
+ *
52
+ * Only numeric weights are supported in the configuration.
53
+ *
54
+ * Automatically set if a single weight is available.
55
+ *
56
+ * @default 400
57
+ */
58
+ weight?:
59
+ | 'thin'
60
+ | 'ultralight'
61
+ | 'light'
62
+ | 'regular'
63
+ | 'medium'
64
+ | 'semibold'
65
+ | 'bold'
66
+ | 100
67
+ | 200
68
+ | 300
69
+ | 400
70
+ | 500
71
+ | 600
72
+ | 700;
73
+ /**
74
+ * The size of the symbol.
75
+ *
76
+ * @default 24
77
+ */
78
+ size?: number;
79
+ /**
80
+ * The color of the symbol.
81
+ *
82
+ * @default 'black'
83
+ */
84
+ color?: ColorValue;
85
+ };
86
+
87
+ export type SFSymbolScale = 'small' | 'medium' | 'large';
88
+
89
+ export type SFSymbolMode =
90
+ | 'monochrome'
91
+ | 'hierarchical'
92
+ | 'palette'
93
+ | 'multicolor';
94
+
95
+ export type SFSymbolAnimationEffect =
96
+ | 'bounce'
97
+ | 'pulse'
98
+ | 'appear'
99
+ | 'disappear'
100
+ | 'variableColor'
101
+ | 'breathe'
102
+ | 'wiggle'
103
+ | 'rotate';
104
+
105
+ export type SFSymbolAnimationConfig = {
106
+ /**
107
+ * The animation effect to apply.
108
+ */
109
+ effect: SFSymbolAnimationEffect;
110
+ /**
111
+ * Whether the animation repeats continuously.
112
+ *
113
+ * @default false
114
+ */
115
+ repeating?: boolean;
116
+ /**
117
+ * Number of times to repeat the animation.
118
+ * Ignored if `repeating` is `true`.
119
+ */
120
+ repeatCount?: number;
121
+ /**
122
+ * Speed multiplier for the animation.
123
+ *
124
+ * @default 1
125
+ */
126
+ speed?: number;
127
+ /**
128
+ * Whether to animate the whole symbol at once or layer by layer.
129
+ *
130
+ * @default false
131
+ */
132
+ wholeSymbol?: boolean;
133
+ /**
134
+ * Direction of the animation.
135
+ * Applicable to `bounce` and `wiggle`.
136
+ */
137
+ direction?: 'up' | 'down';
138
+ /**
139
+ * Whether the variable color effect reverses with each cycle.
140
+ * Only applicable to `variableColor`.
141
+ *
142
+ * @default false
143
+ */
144
+ reversing?: boolean;
145
+ /**
146
+ * Whether each layer remains changed until the end of the cycle.
147
+ * Only applicable to `variableColor`.
148
+ *
149
+ * @default false
150
+ */
151
+ cumulative?: boolean;
152
+ };
153
+
154
+ export type SFSymbolAnimation =
155
+ | SFSymbolAnimationEffect
156
+ | SFSymbolAnimationConfig;
157
+
158
+ export type SFSymbolOptions = {
159
+ /**
160
+ * The name of the SF Symbol to display.
161
+ */
162
+ name: import('sf-symbols-typescript').SFSymbol;
163
+ /**
164
+ * The size of the symbol.
165
+ * @default 24
166
+ */
167
+ size?: number;
168
+ /**
169
+ * The color of the symbol.
170
+ * Used as the tint color in monochrome mode, and as the fallback for
171
+ * `colors.primary` in hierarchical and palette modes.
172
+ *
173
+ * @default 'black'
174
+ */
175
+ color?: ColorValue;
176
+ /**
177
+ * The weight of the symbol.
178
+ *
179
+ * @default 'regular'
180
+ */
181
+ weight?:
182
+ | keyof typeof FONT_WEIGHTS
183
+ | (typeof FONT_WEIGHTS)[keyof typeof FONT_WEIGHTS];
184
+ /**
185
+ * The scale of the symbol relative to the font size.
186
+ *
187
+ * @default 'medium'
188
+ */
189
+ scale?: SFSymbolScale;
190
+ /**
191
+ * The rendering mode of the symbol.
192
+ * - `monochrome`: Single color tint (default).
193
+ * - `hierarchical`: Derived hierarchy from a single color.
194
+ * - `palette`: Explicit colors for each layer.
195
+ * - `multicolor`: Uses the symbol's built-in multicolor scheme.
196
+ *
197
+ * @default 'monochrome'
198
+ */
199
+ mode?: SFSymbolMode;
200
+ /**
201
+ * The colors for non-monochrome rendering modes.
202
+ * - `hierarchical`: uses `primary` as the base color.
203
+ * - `palette`: uses `primary`, `secondary`, and `tertiary` for each layer.
204
+ * - `multicolor`: ignored.
205
+ *
206
+ * Falls back to `color` for `primary` if not specified.
207
+ */
208
+ colors?: {
209
+ primary?: ColorValue;
210
+ secondary?: ColorValue;
211
+ tertiary?: ColorValue;
212
+ };
213
+ /**
214
+ * The animation effect to apply to the symbol.
215
+ * Requires iOS 17+. Ignored on earlier versions.
216
+ */
217
+ animation?: SFSymbolAnimation;
218
+ };
@@ -2,7 +2,7 @@ import type { Theme } from '@react-navigation/core';
2
2
 
3
3
  import { fonts } from './fonts';
4
4
 
5
- export const DefaultTheme = {
5
+ export const LightTheme = {
6
6
  dark: false,
7
7
  colors: {
8
8
  primary: 'rgb(0, 122, 255)',
@@ -0,0 +1,30 @@
1
+ import type { Theme } from '@react-navigation/core';
2
+ import { PlatformColor } from 'react-native';
3
+
4
+ import { fonts } from './fonts';
5
+
6
+ export const MaterialLightTheme = {
7
+ dark: false,
8
+ colors: {
9
+ primary: PlatformColor('@android:color/system_primary_light'),
10
+ background: PlatformColor('@android:color/system_surface_container_light'),
11
+ card: PlatformColor('@android:color/system_background_light'),
12
+ text: PlatformColor('@android:color/system_on_surface_light'),
13
+ border: PlatformColor('@android:color/system_outline_variant_light'),
14
+ notification: PlatformColor('@android:color/system_error_light'),
15
+ },
16
+ fonts,
17
+ } as const satisfies Theme;
18
+
19
+ export const MaterialDarkTheme = {
20
+ dark: true,
21
+ colors: {
22
+ primary: PlatformColor('@android:color/system_primary_dark'),
23
+ background: PlatformColor('@android:color/system_surface_container_dark'),
24
+ card: PlatformColor('@android:color/system_background_dark'),
25
+ text: PlatformColor('@android:color/system_on_surface_dark'),
26
+ border: PlatformColor('@android:color/system_outline_variant_dark'),
27
+ notification: PlatformColor('@android:color/system_error_dark'),
28
+ },
29
+ fonts,
30
+ } as const satisfies Theme;
@@ -0,0 +1,19 @@
1
+ import type { Theme } from '@react-navigation/core';
2
+
3
+ import { fonts } from './fonts';
4
+
5
+ export const MaterialLightTheme = {
6
+ dark: false,
7
+ get colors(): Theme['colors'] {
8
+ throw new Error('MaterialLightTheme is only supported on Android');
9
+ },
10
+ fonts,
11
+ } as const satisfies Theme;
12
+
13
+ export const MaterialDarkTheme = {
14
+ dark: true,
15
+ get colors(): Theme['colors'] {
16
+ throw new Error('MaterialDarkTheme is only supported on Android');
17
+ },
18
+ fonts,
19
+ } as const satisfies Theme;
@@ -17,11 +17,9 @@ type MinimalState = {
17
17
  };
18
18
 
19
19
  /**
20
- * Helpers to build href or action based on the linking options.
21
- *
22
- * @returns `buildHref` to build an `href` for screen and `buildAction` to build an action from an `href`.
20
+ * Helper to build a href for a screen based on the linking options.
23
21
  */
24
- export function useLinkBuilder() {
22
+ export function useBuildHref() {
25
23
  const navigation = React.useContext(NavigationHelpersContext);
26
24
  const route = React.useContext(NavigationRouteContext);
27
25
 
@@ -30,8 +28,6 @@ export function useLinkBuilder() {
30
28
  const focusedRouteState = useStateForPath();
31
29
 
32
30
  const getPathFromStateHelper = options?.getPathFromState ?? getPathFromState;
33
- const getActionFromStateHelper =
34
- options?.getActionFromState ?? getActionFromState;
35
31
 
36
32
  const buildHref = React.useCallback(
37
33
  (name: string, params?: object) => {
@@ -100,6 +96,18 @@ export function useLinkBuilder() {
100
96
  ]
101
97
  );
102
98
 
99
+ return buildHref;
100
+ }
101
+
102
+ /**
103
+ * Helper to build a navigation action from a href based on the linking options.
104
+ */
105
+ export function useBuildAction() {
106
+ const { options } = React.useContext(LinkingContext);
107
+
108
+ const getActionFromStateHelper =
109
+ options?.getActionFromState ?? getActionFromState;
110
+
103
111
  const buildAction = React.useCallback(
104
112
  (href: string) => {
105
113
  const state = getStateFromHref(href, options);
@@ -117,6 +125,18 @@ export function useLinkBuilder() {
117
125
  [options, getActionFromStateHelper]
118
126
  );
119
127
 
128
+ return buildAction;
129
+ }
130
+
131
+ /**
132
+ * Helpers to build href or action based on the linking options.
133
+ *
134
+ * @returns `buildHref` to build an `href` for screen and `buildAction` to build an action from an `href`.
135
+ */
136
+ export function useLinkBuilder() {
137
+ const buildHref = useBuildHref();
138
+ const buildAction = useBuildAction();
139
+
120
140
  return {
121
141
  buildHref,
122
142
  buildAction,
package/src/useLinkTo.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import { NavigationContainerRefContext } from '@react-navigation/core';
2
2
  import * as React from 'react';
3
3
 
4
- import { useLinkBuilder } from './useLinkBuilder';
4
+ import { useBuildAction } from './useLinkBuilder';
5
5
 
6
6
  /**
7
7
  * Helper to navigate to a screen using a href based on the linking options.
@@ -10,7 +10,7 @@ import { useLinkBuilder } from './useLinkBuilder';
10
10
  */
11
11
  export function useLinkTo() {
12
12
  const navigation = React.useContext(NavigationContainerRefContext);
13
- const { buildAction } = useLinkBuilder();
13
+ const buildAction = useBuildAction();
14
14
 
15
15
  const linkTo = React.useCallback(
16
16
  (href: string) => {
@@ -58,28 +58,39 @@ export function useLinking(
58
58
  return undefined;
59
59
  }
60
60
 
61
- if (enabled !== false && linkingHandlers.size) {
62
- console.error(
63
- [
64
- 'Looks like you have configured linking in multiple places. This is likely an error since deep links should only be handled in one place to avoid conflicts. Make sure that:',
65
- "- You don't have multiple NavigationContainers in the app each with 'linking' enabled",
66
- '- Only a single instance of the root component is rendered',
67
- Platform.OS === 'android'
68
- ? "- You have set 'android:launchMode=singleTask' in the '<activity />' section of the 'AndroidManifest.xml' file to avoid launching multiple instances"
69
- : '',
70
- ]
71
- .join('\n')
72
- .trim()
73
- );
74
- }
75
-
76
61
  const handler = Symbol();
77
62
 
78
63
  if (enabled !== false) {
79
64
  linkingHandlers.add(handler);
80
65
  }
81
66
 
67
+ // In some cases, the effect cleanup may get called out of order
68
+ // This may result in multiple linking handlers being registered
69
+ // For example, when changing the wallpaper on Android
70
+ // Showing the error in a delay avoids false positives
71
+ const timer = setTimeout(() => {
72
+ if (
73
+ enabled !== false &&
74
+ linkingHandlers.size &&
75
+ !(linkingHandlers.size === 1 && linkingHandlers.has(handler))
76
+ ) {
77
+ console.error(
78
+ [
79
+ 'Looks like you have configured linking in multiple places. This is likely an error since deep links should only be handled in one place to avoid conflicts. Make sure that:',
80
+ "- You don't have multiple NavigationContainers in the app each with 'linking' enabled",
81
+ '- Only a single instance of the root component is rendered',
82
+ Platform.OS === 'android'
83
+ ? "- You have set 'android:launchMode=singleTask' in the '<activity />' section of the 'AndroidManifest.xml' file to avoid launching multiple instances"
84
+ : '',
85
+ ]
86
+ .join('\n')
87
+ .trim()
88
+ );
89
+ }
90
+ }, 1000);
91
+
82
92
  return () => {
93
+ clearTimeout(timer);
83
94
  linkingHandlers.delete(handler);
84
95
  };
85
96
  }, [enabled, independent]);
@@ -162,6 +173,18 @@ export function useLinking(
162
173
  const navigation = ref.current;
163
174
  const state = navigation ? getStateFromURL(url) : undefined;
164
175
 
176
+ if (navigation) {
177
+ REACT_NAVIGATION_DEVTOOLS.get(navigation)?.listeners.forEach(
178
+ (listener) => {
179
+ listener({
180
+ type: 'link',
181
+ url,
182
+ state,
183
+ });
184
+ }
185
+ );
186
+ }
187
+
165
188
  if (navigation && state) {
166
189
  const action = getActionFromStateRef.current(state, configRef.current);
167
190
 
@@ -1 +0,0 @@
1
- {"version":3,"names":["fonts","DefaultTheme","dark","colors","primary","background","card","text","border","notification"],"sourceRoot":"../../../src","sources":["theming/DefaultTheme.tsx"],"mappings":";;AAEA,SAASA,KAAK,QAAQ,YAAS;AAE/B,OAAO,MAAMC,YAAY,GAAG;EAC1BC,IAAI,EAAE,KAAK;EACXC,MAAM,EAAE;IACNC,OAAO,EAAE,kBAAkB;IAC3BC,UAAU,EAAE,oBAAoB;IAChCC,IAAI,EAAE,oBAAoB;IAC1BC,IAAI,EAAE,iBAAiB;IACvBC,MAAM,EAAE,oBAAoB;IAC5BC,YAAY,EAAE;EAChB,CAAC;EACDT;AACF,CAA0B","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DefaultTheme.d.ts","sourceRoot":"","sources":["../../../../src/theming/DefaultTheme.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWC,CAAC"}