Skip to content

Commit ae99a1c

Browse files
authored
Preserve pending view transitions through a router revalidation call (#11917)
1 parent 2c6726b commit ae99a1c

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

.changeset/soft-socks-remain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@remix-run/router": patch
3+
---
4+
5+
Preserve pending view transitions through a router revalidation call

packages/router/__tests__/view-transition-test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,74 @@ describe("view transitions", () => {
6666
unsubscribe();
6767
t.router.dispose();
6868
});
69+
70+
it("preserves pending view transitions through router.revalidate()", async () => {
71+
let t = setup({
72+
routes: [{ path: "/" }, { id: "a", path: "/a", loader: true }],
73+
});
74+
let spy = jest.fn();
75+
let unsubscribe = t.router.subscribe(spy);
76+
77+
let A = await t.navigate("/a", { unstable_viewTransition: true });
78+
expect(spy).toHaveBeenCalledTimes(1);
79+
expect(spy.mock.calls[0]).toEqual([
80+
expect.objectContaining({
81+
navigation: expect.objectContaining({ state: "loading" }),
82+
}),
83+
expect.objectContaining({ unstable_viewTransitionOpts: undefined }),
84+
]);
85+
expect(A.loaders.a.stub).toHaveBeenCalledTimes(1);
86+
87+
// Interrupt the navigation loading state with a revalidation
88+
let B = await t.revalidate();
89+
expect(spy).toHaveBeenCalledTimes(3);
90+
expect(spy.mock.calls[1]).toEqual([
91+
expect.objectContaining({
92+
revalidation: "loading",
93+
}),
94+
expect.objectContaining({
95+
unstable_viewTransitionOpts: undefined,
96+
}),
97+
]);
98+
expect(spy.mock.calls[2]).toEqual([
99+
expect.objectContaining({
100+
navigation: expect.objectContaining({ state: "loading" }),
101+
}),
102+
expect.objectContaining({
103+
unstable_viewTransitionOpts: undefined,
104+
}),
105+
]);
106+
expect(spy).toHaveBeenLastCalledWith(
107+
expect.objectContaining({
108+
navigation: expect.objectContaining({ state: "loading" }),
109+
}),
110+
expect.objectContaining({
111+
unstable_viewTransitionOpts: undefined,
112+
})
113+
);
114+
expect(B.loaders.a.stub).toHaveBeenCalledTimes(1);
115+
116+
await A.loaders.a.resolve("A");
117+
await B.loaders.a.resolve("A*");
118+
119+
expect(spy).toHaveBeenCalledTimes(4);
120+
expect(spy.mock.calls[3]).toEqual([
121+
expect.objectContaining({
122+
navigation: IDLE_NAVIGATION,
123+
location: expect.objectContaining({ pathname: "/a" }),
124+
loaderData: {
125+
a: "A*",
126+
},
127+
}),
128+
expect.objectContaining({
129+
unstable_viewTransitionOpts: {
130+
currentLocation: expect.objectContaining({ pathname: "/" }),
131+
nextLocation: expect.objectContaining({ pathname: "/a" }),
132+
},
133+
}),
134+
]);
135+
136+
unsubscribe();
137+
t.router.dispose();
138+
});
69139
});

packages/router/router.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,11 @@ export function createRouter(init: RouterInit): Router {
14791479
startNavigation(
14801480
pendingAction || state.historyAction,
14811481
state.navigation.location,
1482-
{ overrideNavigation: state.navigation }
1482+
{
1483+
overrideNavigation: state.navigation,
1484+
// Proxy through any rending view transition
1485+
enableViewTransition: pendingViewTransitionEnabled === true,
1486+
}
14831487
);
14841488
}
14851489

0 commit comments

Comments
 (0)