@@ -137,6 +137,36 @@ export interface NavigateFunction {
137
137
( delta : number ) : void ;
138
138
}
139
139
140
+ /**
141
+ * When processing relative navigation we want to ignore ancestor routes that
142
+ * do not contribute to the path, such that index/pathless layout routes don't
143
+ * interfere.
144
+ *
145
+ * For example, when moving a route element into an index route and/or a
146
+ * pathless layout route, relative link behavior contained within should stay
147
+ * the same. Both of the following examples should link back to the root:
148
+ *
149
+ * <Route path="/">
150
+ * <Route path="accounts" element={<Link to=".."}>
151
+ * </Route>
152
+ *
153
+ * <Route path="/">
154
+ * <Route path="accounts">
155
+ * <Route element={<AccountsLayout />}> // <-- Does not contribute
156
+ * <Route index element={<Link to=".."} /> // <-- Does not contribute
157
+ * </Route
158
+ * </Route>
159
+ * </Route>
160
+ */
161
+ function getPathContributingMatches ( matches : RouteMatch [ ] ) {
162
+ return matches . filter (
163
+ ( match , index ) =>
164
+ index === 0 ||
165
+ ( ! match . route . index &&
166
+ match . pathnameBase !== matches [ index - 1 ] . pathnameBase )
167
+ ) ;
168
+ }
169
+
140
170
/**
141
171
* Returns an imperative method for changing the location. Used by <Link>s, but
142
172
* may also be used by other elements to change the location.
@@ -155,16 +185,8 @@ export function useNavigate(): NavigateFunction {
155
185
let { matches } = React . useContext ( RouteContext ) ;
156
186
let { pathname : locationPathname } = useLocation ( ) ;
157
187
158
- // Ignore index + pathless matches
159
- let pathContributingMatches = matches . filter (
160
- ( match , index ) =>
161
- index === 0 ||
162
- ( ! match . route . index &&
163
- match . pathnameBase !== matches [ index - 1 ] . pathnameBase )
164
- ) ;
165
-
166
188
let routePathnamesJson = JSON . stringify (
167
- pathContributingMatches . map ( ( match ) => match . pathnameBase )
189
+ getPathContributingMatches ( matches ) . map ( ( match ) => match . pathnameBase )
168
190
) ;
169
191
170
192
let activeRef = React . useRef ( false ) ;
@@ -262,7 +284,7 @@ export function useResolvedPath(to: To): Path {
262
284
let { pathname : locationPathname } = useLocation ( ) ;
263
285
264
286
let routePathnamesJson = JSON . stringify (
265
- matches . map ( ( match ) => match . pathnameBase )
287
+ getPathContributingMatches ( matches ) . map ( ( match ) => match . pathnameBase )
266
288
) ;
267
289
268
290
return React . useMemo (
0 commit comments