@react-navigation/core 8.0.0-alpha.33 → 8.0.0-alpha.34

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 (78) hide show
  1. package/lib/module/NavigationBuilderContext.js +8 -13
  2. package/lib/module/NavigationBuilderContext.js.map +1 -1
  3. package/lib/module/NavigationIndependentTree.js +42 -15
  4. package/lib/module/NavigationIndependentTree.js.map +1 -1
  5. package/lib/module/getPathFromState.js +41 -16
  6. package/lib/module/getPathFromState.js.map +1 -1
  7. package/lib/module/getPatternParts.js +43 -12
  8. package/lib/module/getPatternParts.js.map +1 -1
  9. package/lib/module/getStateFromPath.js +175 -109
  10. package/lib/module/getStateFromPath.js.map +1 -1
  11. package/lib/module/index.js +1 -0
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/module/useDescriptors.js +2 -2
  14. package/lib/module/useDescriptors.js.map +1 -1
  15. package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
  16. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
  17. package/lib/module/useNavigationBuilder.js +2 -2
  18. package/lib/module/useNavigationBuilder.js.map +1 -1
  19. package/lib/module/useNavigationCache.js +3 -3
  20. package/lib/module/useNavigationCache.js.map +1 -1
  21. package/lib/module/useNavigationHelpers.js +2 -2
  22. package/lib/module/useNavigationHelpers.js.map +1 -1
  23. package/lib/module/useOnAction.js +6 -4
  24. package/lib/module/useOnAction.js.map +1 -1
  25. package/lib/module/useOnGetNavigation.js +2 -2
  26. package/lib/module/useOnGetNavigation.js.map +1 -1
  27. package/lib/module/useOnGetState.js +2 -2
  28. package/lib/module/useOnGetState.js.map +1 -1
  29. package/lib/module/useOnPreventRemove.js +2 -2
  30. package/lib/module/useOnPreventRemove.js.map +1 -1
  31. package/lib/module/useOnRouteFocus.js +2 -2
  32. package/lib/module/useOnRouteFocus.js.map +1 -1
  33. package/lib/module/useOptionsGetters.js +2 -4
  34. package/lib/module/useOptionsGetters.js.map +1 -1
  35. package/lib/module/useScheduleUpdate.js +2 -2
  36. package/lib/module/useScheduleUpdate.js.map +1 -1
  37. package/lib/typescript/src/NavigationBuilderContext.d.ts +8 -5
  38. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  39. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  40. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  41. package/lib/typescript/src/getPatternParts.d.ts +4 -2
  42. package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
  43. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  44. package/lib/typescript/src/index.d.ts +1 -0
  45. package/lib/typescript/src/index.d.ts.map +1 -1
  46. package/lib/typescript/src/types.d.ts +1 -1
  47. package/lib/typescript/src/types.d.ts.map +1 -1
  48. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  49. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  50. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  51. package/lib/typescript/src/useOnGetNavigation.d.ts.map +1 -1
  52. package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
  53. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  54. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  55. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  56. package/lib/typescript/src/utilities.d.ts +3 -0
  57. package/lib/typescript/src/utilities.d.ts.map +1 -1
  58. package/package.json +2 -3
  59. package/src/NavigationBuilderContext.tsx +21 -17
  60. package/src/NavigationIndependentTree.tsx +48 -22
  61. package/src/getPathFromState.tsx +63 -15
  62. package/src/getPatternParts.tsx +75 -14
  63. package/src/getStateFromPath.tsx +250 -113
  64. package/src/index.tsx +1 -0
  65. package/src/types.tsx +1 -1
  66. package/src/useDescriptors.tsx +2 -1
  67. package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
  68. package/src/useNavigationBuilder.tsx +2 -4
  69. package/src/useNavigationCache.tsx +3 -3
  70. package/src/useNavigationHelpers.tsx +2 -2
  71. package/src/useOnAction.tsx +6 -5
  72. package/src/useOnGetNavigation.tsx +3 -2
  73. package/src/useOnGetState.tsx +4 -2
  74. package/src/useOnPreventRemove.tsx +4 -2
  75. package/src/useOnRouteFocus.tsx +2 -4
  76. package/src/useOptionsGetters.tsx +3 -2
  77. package/src/useScheduleUpdate.tsx +2 -2
  78. package/src/utilities.tsx +5 -2
@@ -1,8 +1,11 @@
1
+ export type PatternPartRepeat = 'zero-or-more' | 'one-or-more';
2
+
1
3
  export type PatternPart = {
2
4
  segment: string;
3
- param?: string;
4
- regex?: string;
5
+ name?: string;
6
+ pattern?: string;
5
7
  optional?: boolean;
8
+ repeat?: PatternPartRepeat;
6
9
  };
7
10
 
8
11
  /**
@@ -15,6 +18,7 @@ export function getPatternParts(path: string): PatternPart[] {
15
18
 
16
19
  let isRegex = false;
17
20
  let isParam = false;
21
+ let hasRepeat = false;
18
22
  let isEscaped = false;
19
23
  let isInCharClass = false;
20
24
  let regexInnerParens = 0;
@@ -55,7 +59,7 @@ export function getPatternParts(path: string): PatternPart[] {
55
59
  // The ')' is part of the regex if we're already inside one
56
60
  regexInnerParens--;
57
61
  } else {
58
- current.regex += char;
62
+ current.pattern += char;
59
63
  isRegex = false;
60
64
  isParam = false;
61
65
  }
@@ -65,7 +69,7 @@ export function getPatternParts(path: string): PatternPart[] {
65
69
  );
66
70
  }
67
71
  } else if (char === '?' && !isRegex) {
68
- if (current.param) {
72
+ if (current.name) {
69
73
  isParam = false;
70
74
 
71
75
  current.optional = true;
@@ -74,6 +78,27 @@ export function getPatternParts(path: string): PatternPart[] {
74
78
  `Encountered '?' without preceding ':' in path: ${path}`
75
79
  );
76
80
  }
81
+ } else if (
82
+ current.name &&
83
+ !isRegex &&
84
+ (char === '*' || char === '+') &&
85
+ (path[i + 1] == null ||
86
+ path[i + 1] === '/' ||
87
+ path[i + 1] === '?' ||
88
+ path[i + 1] === '*' ||
89
+ path[i + 1] === '+')
90
+ ) {
91
+ if (
92
+ current.optional ||
93
+ (path[i + 1] !== undefined && path[i + 1] !== '/')
94
+ ) {
95
+ throw new Error(`Cannot combine path param modifiers in path: ${path}`);
96
+ }
97
+
98
+ isParam = false;
99
+
100
+ current.repeat = char === '*' ? 'zero-or-more' : 'one-or-more';
101
+ hasRepeat = true;
77
102
  } else if (char == null || (char === '/' && !isRegex)) {
78
103
  isParam = false;
79
104
 
@@ -84,12 +109,12 @@ export function getPatternParts(path: string): PatternPart[] {
84
109
  continue;
85
110
  }
86
111
 
87
- if (current.param) {
88
- current.param = current.param.replace(/^:/, '');
112
+ if (current.name) {
113
+ current.name = current.name.replace(/^:/, '');
89
114
  }
90
115
 
91
- if (current.regex) {
92
- current.regex = current.regex.replace(/^\(/, '').replace(/\)$/, '');
116
+ if (current.pattern) {
117
+ current.pattern = current.pattern.replace(/^\(/, '').replace(/\)$/, '');
93
118
  }
94
119
 
95
120
  parts.push(current);
@@ -102,8 +127,8 @@ export function getPatternParts(path: string): PatternPart[] {
102
127
  }
103
128
 
104
129
  if (isRegex) {
105
- current.regex = current.regex || '';
106
- current.regex += char;
130
+ current.pattern = current.pattern || '';
131
+ current.pattern += char;
107
132
 
108
133
  // Track escapes and character classes so parens inside them are not special
109
134
  if (isEscaped) {
@@ -118,8 +143,8 @@ export function getPatternParts(path: string): PatternPart[] {
118
143
  }
119
144
 
120
145
  if (isParam && !isRegex) {
121
- current.param = current.param || '';
122
- current.param += char;
146
+ current.name = current.name || '';
147
+ current.name += char;
123
148
  }
124
149
  }
125
150
 
@@ -127,7 +152,7 @@ export function getPatternParts(path: string): PatternPart[] {
127
152
  throw new Error(`Could not find closing ')' in path: ${path}`);
128
153
  }
129
154
 
130
- const params = parts.map((part) => part.param).filter(Boolean);
155
+ const params = parts.map((part) => part.name).filter(Boolean);
131
156
 
132
157
  for (const [index, param] of params.entries()) {
133
158
  if (params.indexOf(param) !== index) {
@@ -135,13 +160,49 @@ export function getPatternParts(path: string): PatternPart[] {
135
160
  }
136
161
  }
137
162
 
163
+ if (hasRepeat) {
164
+ validateRepeatedParts(parts, path);
165
+ }
166
+
138
167
  return parts;
139
168
  }
140
169
 
170
+ function validateRepeatedParts(parts: PatternPart[], path: string) {
171
+ let variablePart: PatternPart | undefined;
172
+
173
+ for (const part of parts) {
174
+ if (!part.name && part.segment !== '*') {
175
+ variablePart = undefined;
176
+ continue;
177
+ }
178
+
179
+ if (!part.repeat && !part.optional && part.segment !== '*') {
180
+ continue;
181
+ }
182
+
183
+ if (variablePart && (variablePart.repeat || part.repeat)) {
184
+ throw new Error(
185
+ `A repeated param must be separated from optional, repeated, or wildcard segments by a static segment: ${path}`
186
+ );
187
+ }
188
+
189
+ variablePart = part;
190
+ }
191
+ }
192
+
141
193
  export function combinePatternParts<T extends PatternPart>(
142
194
  parentParts: T[],
143
195
  parts: T[],
144
196
  exact = false
145
197
  ): T[] {
146
- return exact ? parts : [...parentParts, ...parts];
198
+ const combined = exact ? parts : [...parentParts, ...parts];
199
+
200
+ if (combined.some((part) => part.repeat)) {
201
+ validateRepeatedParts(
202
+ combined,
203
+ combined.map((part) => part.segment).join('/')
204
+ );
205
+ }
206
+
207
+ return combined;
147
208
  }