diff --git a/e2e/react-router/basic-file-based/src/routeTree.gen.ts b/e2e/react-router/basic-file-based/src/routeTree.gen.ts index efa8b81d76c..588b2acb7b5 100644 --- a/e2e/react-router/basic-file-based/src/routeTree.gen.ts +++ b/e2e/react-router/basic-file-based/src/routeTree.gen.ts @@ -12,6 +12,7 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as RemountDepsRouteImport } from './routes/remountDeps' import { Route as PostsRouteImport } from './routes/posts' import { Route as NotRemountDepsRouteImport } from './routes/notRemountDeps' +import { Route as HoverPreloadHashRouteImport } from './routes/hover-preload-hash' import { Route as EditingBRouteImport } from './routes/editing-b' import { Route as EditingARouteImport } from './routes/editing-a' import { Route as ComponentTypesTestRouteImport } from './routes/component-types-test' @@ -125,6 +126,11 @@ const NotRemountDepsRoute = NotRemountDepsRouteImport.update({ path: '/notRemountDeps', getParentRoute: () => rootRouteImport, } as any) +const HoverPreloadHashRoute = HoverPreloadHashRouteImport.update({ + id: '/hover-preload-hash', + path: '/hover-preload-hash', + getParentRoute: () => rootRouteImport, +} as any) const EditingBRoute = EditingBRouteImport.update({ id: '/editing-b', path: '/editing-b', @@ -659,6 +665,7 @@ export interface FileRoutesByFullPath { '/component-types-test': typeof ComponentTypesTestRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/hover-preload-hash': typeof HoverPreloadHashRoute '/notRemountDeps': typeof NotRemountDepsRoute '/posts': typeof PostsRouteWithChildren '/remountDeps': typeof RemountDepsRoute @@ -757,6 +764,7 @@ export interface FileRoutesByTo { '/component-types-test': typeof ComponentTypesTestRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/hover-preload-hash': typeof HoverPreloadHashRoute '/notRemountDeps': typeof NotRemountDepsRoute '/remountDeps': typeof RemountDepsRoute '/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren @@ -849,6 +857,7 @@ export interface FileRoutesById { '/component-types-test': typeof ComponentTypesTestRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/hover-preload-hash': typeof HoverPreloadHashRoute '/notRemountDeps': typeof NotRemountDepsRoute '/posts': typeof PostsRouteWithChildren '/remountDeps': typeof RemountDepsRoute @@ -952,6 +961,7 @@ export interface FileRouteTypes { | '/component-types-test' | '/editing-a' | '/editing-b' + | '/hover-preload-hash' | '/notRemountDeps' | '/posts' | '/remountDeps' @@ -1050,6 +1060,7 @@ export interface FileRouteTypes { | '/component-types-test' | '/editing-a' | '/editing-b' + | '/hover-preload-hash' | '/notRemountDeps' | '/remountDeps' | '/non-nested/deep' @@ -1141,6 +1152,7 @@ export interface FileRouteTypes { | '/component-types-test' | '/editing-a' | '/editing-b' + | '/hover-preload-hash' | '/notRemountDeps' | '/posts' | '/remountDeps' @@ -1244,6 +1256,7 @@ export interface RootRouteChildren { ComponentTypesTestRoute: typeof ComponentTypesTestRoute EditingARoute: typeof EditingARoute EditingBRoute: typeof EditingBRoute + HoverPreloadHashRoute: typeof HoverPreloadHashRoute NotRemountDepsRoute: typeof NotRemountDepsRoute PostsRoute: typeof PostsRouteWithChildren RemountDepsRoute: typeof RemountDepsRoute @@ -1300,6 +1313,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof NotRemountDepsRouteImport parentRoute: typeof rootRouteImport } + '/hover-preload-hash': { + id: '/hover-preload-hash' + path: '/hover-preload-hash' + fullPath: '/hover-preload-hash' + preLoaderRoute: typeof HoverPreloadHashRouteImport + parentRoute: typeof rootRouteImport + } '/editing-b': { id: '/editing-b' path: '/editing-b' @@ -2402,6 +2422,7 @@ const rootRouteChildren: RootRouteChildren = { ComponentTypesTestRoute: ComponentTypesTestRoute, EditingARoute: EditingARoute, EditingBRoute: EditingBRoute, + HoverPreloadHashRoute: HoverPreloadHashRoute, NotRemountDepsRoute: NotRemountDepsRoute, PostsRoute: PostsRouteWithChildren, RemountDepsRoute: RemountDepsRoute, diff --git a/e2e/react-router/basic-file-based/src/routes/hover-preload-hash.tsx b/e2e/react-router/basic-file-based/src/routes/hover-preload-hash.tsx new file mode 100644 index 00000000000..6b62bac50a8 --- /dev/null +++ b/e2e/react-router/basic-file-based/src/routes/hover-preload-hash.tsx @@ -0,0 +1,265 @@ +import { Link, createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/hover-preload-hash')({ + component: Page, +}) + +function Page() { + return ( + <> +
Hello from About!
+ + To hash + + +

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

Hash is here

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+ + ) +} diff --git a/e2e/react-router/basic-file-based/tests/hover-preload-hash.spec.ts b/e2e/react-router/basic-file-based/tests/hover-preload-hash.spec.ts new file mode 100644 index 00000000000..b090c2a6b7e --- /dev/null +++ b/e2e/react-router/basic-file-based/tests/hover-preload-hash.spec.ts @@ -0,0 +1,24 @@ +import { expect, test } from '@playwright/test' +import { toRuntimePath } from '@tanstack/router-e2e-utils' + +test('clicking hash link then hovering another link does not scroll back to hash', async ({ + page, +}) => { + // Go to the page without hash + await page.goto(toRuntimePath('/hover-preload-hash')) + + // Click the hash link to navigate to position1 + await page.getByTestId('link-to-hash').click() + await expect(page.locator('#position1')).toBeInViewport() + + // Scroll up so position1 is no longer in view + await page.evaluate(() => window.scrollTo(0, 0)) + await expect(page.locator('#position1')).not.toBeInViewport() + + // Hover the link to trigger intent preload (should NOT scroll back) + await page.getByTestId('link-to-only-route-inside-group').hover() + await page.waitForTimeout(400) + + // Ensure we did not jump back to the hash target + await expect(page.locator('#position1')).not.toBeInViewport() +}) diff --git a/e2e/solid-router/basic-file-based/src/routeTree.gen.ts b/e2e/solid-router/basic-file-based/src/routeTree.gen.ts index b836ba6cff6..bf5f4523c77 100644 --- a/e2e/solid-router/basic-file-based/src/routeTree.gen.ts +++ b/e2e/solid-router/basic-file-based/src/routeTree.gen.ts @@ -12,6 +12,7 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as RemountDepsRouteImport } from './routes/remountDeps' import { Route as PostsRouteImport } from './routes/posts' import { Route as NotRemountDepsRouteImport } from './routes/notRemountDeps' +import { Route as HoverPreloadHashRouteImport } from './routes/hover-preload-hash' import { Route as EditingBRouteImport } from './routes/editing-b' import { Route as EditingARouteImport } from './routes/editing-a' import { Route as ComponentTypesTestRouteImport } from './routes/component-types-test' @@ -126,6 +127,11 @@ const NotRemountDepsRoute = NotRemountDepsRouteImport.update({ path: '/notRemountDeps', getParentRoute: () => rootRouteImport, } as any) +const HoverPreloadHashRoute = HoverPreloadHashRouteImport.update({ + id: '/hover-preload-hash', + path: '/hover-preload-hash', + getParentRoute: () => rootRouteImport, +} as any) const EditingBRoute = EditingBRouteImport.update({ id: '/editing-b', path: '/editing-b', @@ -666,6 +672,7 @@ export interface FileRoutesByFullPath { '/component-types-test': typeof ComponentTypesTestRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/hover-preload-hash': typeof HoverPreloadHashRoute '/notRemountDeps': typeof NotRemountDepsRoute '/posts': typeof PostsRouteWithChildren '/remountDeps': typeof RemountDepsRoute @@ -765,6 +772,7 @@ export interface FileRoutesByTo { '/component-types-test': typeof ComponentTypesTestRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/hover-preload-hash': typeof HoverPreloadHashRoute '/notRemountDeps': typeof NotRemountDepsRoute '/remountDeps': typeof RemountDepsRoute '/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren @@ -858,6 +866,7 @@ export interface FileRoutesById { '/component-types-test': typeof ComponentTypesTestRoute '/editing-a': typeof EditingARoute '/editing-b': typeof EditingBRoute + '/hover-preload-hash': typeof HoverPreloadHashRoute '/notRemountDeps': typeof NotRemountDepsRoute '/posts': typeof PostsRouteWithChildren '/remountDeps': typeof RemountDepsRoute @@ -962,6 +971,7 @@ export interface FileRouteTypes { | '/component-types-test' | '/editing-a' | '/editing-b' + | '/hover-preload-hash' | '/notRemountDeps' | '/posts' | '/remountDeps' @@ -1061,6 +1071,7 @@ export interface FileRouteTypes { | '/component-types-test' | '/editing-a' | '/editing-b' + | '/hover-preload-hash' | '/notRemountDeps' | '/remountDeps' | '/non-nested/deep' @@ -1153,6 +1164,7 @@ export interface FileRouteTypes { | '/component-types-test' | '/editing-a' | '/editing-b' + | '/hover-preload-hash' | '/notRemountDeps' | '/posts' | '/remountDeps' @@ -1257,6 +1269,7 @@ export interface RootRouteChildren { ComponentTypesTestRoute: typeof ComponentTypesTestRoute EditingARoute: typeof EditingARoute EditingBRoute: typeof EditingBRoute + HoverPreloadHashRoute: typeof HoverPreloadHashRoute NotRemountDepsRoute: typeof NotRemountDepsRoute PostsRoute: typeof PostsRouteWithChildren RemountDepsRoute: typeof RemountDepsRoute @@ -1314,6 +1327,13 @@ declare module '@tanstack/solid-router' { preLoaderRoute: typeof NotRemountDepsRouteImport parentRoute: typeof rootRouteImport } + '/hover-preload-hash': { + id: '/hover-preload-hash' + path: '/hover-preload-hash' + fullPath: '/hover-preload-hash' + preLoaderRoute: typeof HoverPreloadHashRouteImport + parentRoute: typeof rootRouteImport + } '/editing-b': { id: '/editing-b' path: '/editing-b' @@ -2423,6 +2443,7 @@ const rootRouteChildren: RootRouteChildren = { ComponentTypesTestRoute: ComponentTypesTestRoute, EditingARoute: EditingARoute, EditingBRoute: EditingBRoute, + HoverPreloadHashRoute: HoverPreloadHashRoute, NotRemountDepsRoute: NotRemountDepsRoute, PostsRoute: PostsRouteWithChildren, RemountDepsRoute: RemountDepsRoute, diff --git a/e2e/solid-router/basic-file-based/src/routes/hover-preload-hash.tsx b/e2e/solid-router/basic-file-based/src/routes/hover-preload-hash.tsx new file mode 100644 index 00000000000..9b9da8bb900 --- /dev/null +++ b/e2e/solid-router/basic-file-based/src/routes/hover-preload-hash.tsx @@ -0,0 +1,265 @@ +import { Link, createFileRoute } from '@tanstack/solid-router' + +export const Route = createFileRoute('/hover-preload-hash')({ + component: Page, +}) + +function Page() { + return ( + <> +
Hello from About!
+ + To hash + + +

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

Hash is here

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+

+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy + eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit + amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam + nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea + rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem + ipsum dolor sit amet. +

+ + ) +} diff --git a/e2e/solid-router/basic-file-based/tests/hover-preload-hash.spec.ts b/e2e/solid-router/basic-file-based/tests/hover-preload-hash.spec.ts new file mode 100644 index 00000000000..b090c2a6b7e --- /dev/null +++ b/e2e/solid-router/basic-file-based/tests/hover-preload-hash.spec.ts @@ -0,0 +1,24 @@ +import { expect, test } from '@playwright/test' +import { toRuntimePath } from '@tanstack/router-e2e-utils' + +test('clicking hash link then hovering another link does not scroll back to hash', async ({ + page, +}) => { + // Go to the page without hash + await page.goto(toRuntimePath('/hover-preload-hash')) + + // Click the hash link to navigate to position1 + await page.getByTestId('link-to-hash').click() + await expect(page.locator('#position1')).toBeInViewport() + + // Scroll up so position1 is no longer in view + await page.evaluate(() => window.scrollTo(0, 0)) + await expect(page.locator('#position1')).not.toBeInViewport() + + // Hover the link to trigger intent preload (should NOT scroll back) + await page.getByTestId('link-to-only-route-inside-group').hover() + await page.waitForTimeout(400) + + // Ensure we did not jump back to the hash target + await expect(page.locator('#position1')).not.toBeInViewport() +}) diff --git a/packages/react-router/src/Transitioner.tsx b/packages/react-router/src/Transitioner.tsx index 04e140acfcd..f547cdd5f58 100644 --- a/packages/react-router/src/Transitioner.tsx +++ b/packages/react-router/src/Transitioner.tsx @@ -108,20 +108,22 @@ export function Transitioner() { }, [isPagePending, previousIsPagePending, router]) useLayoutEffect(() => { - // The router was pending and now it's not if (previousIsAnyPending && !isAnyPending) { + const changeInfo = getLocationChangeInfo(router.state) router.emit({ type: 'onResolved', - ...getLocationChangeInfo(router.state), + ...changeInfo, }) - router.__store.setState((s) => ({ + router.__store.setState((s: typeof router.state) => ({ ...s, status: 'idle', resolvedLocation: s.location, })) - handleHashScroll(router) + if (changeInfo.hrefChanged) { + handleHashScroll(router) + } } }, [isAnyPending, previousIsAnyPending, router]) diff --git a/packages/solid-router/src/Transitioner.tsx b/packages/solid-router/src/Transitioner.tsx index fe2b29544c4..1708f1bcb8c 100644 --- a/packages/solid-router/src/Transitioner.tsx +++ b/packages/solid-router/src/Transitioner.tsx @@ -122,11 +122,11 @@ export function Transitioner() { Solid.on( [isAnyPending, previousIsAnyPending], ([isAnyPending, previousIsAnyPending]) => { - // The router was pending and now it's not if (previousIsAnyPending.previous && !isAnyPending) { + const changeInfo = getLocationChangeInfo(router.state) router.emit({ type: 'onResolved', - ...getLocationChangeInfo(router.state), + ...changeInfo, }) router.__store.setState((s) => ({ @@ -135,7 +135,9 @@ export function Transitioner() { resolvedLocation: s.location, })) - handleHashScroll(router) + if (changeInfo.hrefChanged) { + handleHashScroll(router) + } } }, ),