File tree Expand file tree Collapse file tree 5 files changed +96
-4
lines changed Expand file tree Collapse file tree 5 files changed +96
-4
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ " @remix-run/router " : patch
3
+ ---
4
+
5
+ Ignore pathless layout routes when looking for proper submission action function
Original file line number Diff line number Diff line change 107
107
},
108
108
"filesize" : {
109
109
"packages/router/dist/router.js" : {
110
- "none" : " 100 kB"
110
+ "none" : " 101 kB"
111
111
},
112
112
"packages/react-router/dist/react-router.production.min.js" : {
113
113
"none" : " 12.5 kB"
Original file line number Diff line number Diff line change @@ -2859,6 +2859,56 @@ describe("a router", () => {
2859
2859
} ) ;
2860
2860
} ) ;
2861
2861
2862
+ it ( "uses the proper action for pathless layout routes" , async ( ) => {
2863
+ let t = setup ( {
2864
+ routes : [
2865
+ {
2866
+ id : "parent" ,
2867
+ path : "/parent" ,
2868
+ action : true ,
2869
+ children : [
2870
+ {
2871
+ hasErrorBoundary : true ,
2872
+ children : [
2873
+ {
2874
+ id : "index" ,
2875
+ index : true ,
2876
+ action : true ,
2877
+ } ,
2878
+ ] ,
2879
+ } ,
2880
+ ] ,
2881
+ } ,
2882
+ ] ,
2883
+ } ) ;
2884
+ debugger ;
2885
+ let A = await t . navigate ( "/parent" , {
2886
+ formMethod : "post" ,
2887
+ formData : createFormData ( { gosh : "dang" } ) ,
2888
+ } ) ;
2889
+ await A . actions . parent . resolve ( "PARENT" ) ;
2890
+ expect ( t . router . state ) . toMatchObject ( {
2891
+ location : { pathname : "/parent" } ,
2892
+ actionData : {
2893
+ parent : "PARENT" ,
2894
+ } ,
2895
+ errors : null ,
2896
+ } ) ;
2897
+
2898
+ let B = await t . navigate ( "/parent?index" , {
2899
+ formMethod : "post" ,
2900
+ formData : createFormData ( { gosh : "dang" } ) ,
2901
+ } ) ;
2902
+ await B . actions . index . resolve ( "INDEX" ) ;
2903
+ expect ( t . router . state ) . toMatchObject ( {
2904
+ location : { pathname : "/parent" , search : "?index" } ,
2905
+ actionData : {
2906
+ index : "INDEX" ,
2907
+ } ,
2908
+ errors : null ,
2909
+ } ) ;
2910
+ } ) ;
2911
+
2862
2912
it ( "retains the index match when submitting to a layout route" , async ( ) => {
2863
2913
let t = setup ( {
2864
2914
routes : [
Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ import {
25
25
ErrorResponse ,
26
26
ResultType ,
27
27
convertRoutesToDataRoutes ,
28
+ getPathContributingMatches ,
28
29
invariant ,
29
30
isRouteErrorResponse ,
30
31
matchRoutes ,
@@ -2838,11 +2839,15 @@ function getTargetMatch(
2838
2839
typeof location === "string" ? parsePath ( location ) . search : location . search ;
2839
2840
if (
2840
2841
matches [ matches . length - 1 ] . route . index &&
2841
- ! hasNakedIndexQuery ( search || "" )
2842
+ hasNakedIndexQuery ( search || "" )
2842
2843
) {
2843
- return matches . slice ( - 2 ) [ 0 ] ;
2844
+ // Return the leaf index route when index is present
2845
+ return matches [ matches . length - 1 ] ;
2844
2846
}
2845
- return matches . slice ( - 1 ) [ 0 ] ;
2847
+ // Otherwise grab the deepest "path contributing" match (ignoring index and
2848
+ // pathless layout routes)
2849
+ let pathMatches = getPathContributingMatches ( matches ) ;
2850
+ return pathMatches [ pathMatches . length - 1 ] ;
2846
2851
}
2847
2852
2848
2853
function createURL ( location : Location | string ) : URL {
Original file line number Diff line number Diff line change @@ -835,6 +835,38 @@ function getInvalidPathError(
835
835
) ;
836
836
}
837
837
838
+ /**
839
+ * When processing relative navigation we want to ignore ancestor routes that
840
+ * do not contribute to the path, such that index/pathless layout routes don't
841
+ * interfere.
842
+ *
843
+ * For example, when moving a route element into an index route and/or a
844
+ * pathless layout route, relative link behavior contained within should stay
845
+ * the same. Both of the following examples should link back to the root:
846
+ *
847
+ * <Route path="/">
848
+ * <Route path="accounts" element={<Link to=".."}>
849
+ * </Route>
850
+ *
851
+ * <Route path="/">
852
+ * <Route path="accounts">
853
+ * <Route element={<AccountsLayout />}> // <-- Does not contribute
854
+ * <Route index element={<Link to=".."} /> // <-- Does not contribute
855
+ * </Route
856
+ * </Route>
857
+ * </Route>
858
+ */
859
+ export function getPathContributingMatches <
860
+ T extends AgnosticRouteMatch = AgnosticRouteMatch
861
+ > ( matches : T [ ] ) {
862
+ return matches . filter (
863
+ ( match , index ) =>
864
+ index === 0 ||
865
+ ( ! match . route . index &&
866
+ match . pathnameBase !== matches [ index - 1 ] . pathnameBase )
867
+ ) ;
868
+ }
869
+
838
870
/**
839
871
* @private
840
872
*/
You can’t perform that action at this time.
0 commit comments