diff --git a/.changeset/witty-spoons-hug.md b/.changeset/witty-spoons-hug.md new file mode 100644 index 00000000000..33ef7f991d2 --- /dev/null +++ b/.changeset/witty-spoons-hug.md @@ -0,0 +1,5 @@ +--- +'@builder.io/qwik-city': patch +--- + +🩹 SPA Link now handle subsequent onQVisible$ passed as props. diff --git a/packages/qwik-city/src/runtime/src/link-component.tsx b/packages/qwik-city/src/runtime/src/link-component.tsx index 765463fc3fb..e2c8a7321b8 100644 --- a/packages/qwik-city/src/runtime/src/link-component.tsx +++ b/packages/qwik-city/src/runtime/src/link-component.tsx @@ -7,6 +7,8 @@ import { useSignal, useVisibleTask$, untrack, + type EventHandler, + type QwikVisibleEvent, } from '@builder.io/qwik'; import { getClientNavPath, shouldPreload } from './utils'; import { loadClientData } from './use-endpoint'; @@ -85,6 +87,22 @@ export const Link = component$((props) => { useVisibleTask$(({ track }) => { track(() => loc.url.pathname); + // We need to trigger the onQVisible$ in the visible task for it to fire on subsequent route navigations + const handler = linkProps.onQVisible$; + if (handler) { + const event = new CustomEvent('qvisible') as QwikVisibleEvent; + + if (Array.isArray(handler)) { + (handler as any) + .flat(10) + .forEach((handler: EventHandler) => + handler?.(event, anchorRef.value!) + ); + } else { + handler?.(event, anchorRef.value!); + } + } + // Don't prefetch on visible in dev mode if (!isDev && anchorRef.value) { handlePrefetch?.(undefined, anchorRef.value!); @@ -101,6 +119,8 @@ export const Link = component$((props) => { data-prefetch={prefetchData} onMouseOver$={[linkProps.onMouseOver$, handlePrefetch]} onFocus$={[linkProps.onFocus$, handlePrefetch]} + // We need to prevent the onQVisible$ from being called twice since it is handled in the visible task + onQVisible$={[]} > diff --git a/starters/apps/preloader-test/src/routes/counters/index.tsx b/starters/apps/preloader-test/src/routes/counters/index.tsx index 8d5c4b2dbb7..3f665700e71 100644 --- a/starters/apps/preloader-test/src/routes/counters/index.tsx +++ b/starters/apps/preloader-test/src/routes/counters/index.tsx @@ -1,5 +1,5 @@ import { component$ } from "@builder.io/qwik"; - +import { Link } from "@builder.io/qwik-city"; import Counter1 from "~/components/generated/counter1"; import Counter2 from "~/components/generated/counter2"; import Counter3 from "~/components/generated/counter3"; @@ -213,6 +213,12 @@ export default component$(() => { + console.log("visible below fold")} + > + Home + ); }); diff --git a/starters/apps/preloader-test/src/routes/hidden/index.tsx b/starters/apps/preloader-test/src/routes/hidden/index.tsx new file mode 100644 index 00000000000..de599d54e00 --- /dev/null +++ b/starters/apps/preloader-test/src/routes/hidden/index.tsx @@ -0,0 +1,5 @@ +import { component$ } from "@builder.io/qwik"; + +export default component$(() => { + return
Hidden
; +}); diff --git a/starters/apps/preloader-test/src/routes/layout.tsx b/starters/apps/preloader-test/src/routes/layout.tsx index d78188c0fc1..bf44e47e9d8 100644 --- a/starters/apps/preloader-test/src/routes/layout.tsx +++ b/starters/apps/preloader-test/src/routes/layout.tsx @@ -56,7 +56,7 @@ export default component$(() => { } `); - const isSPA = useSignal(false); + const isSPA = useSignal(true); const LinkCmp = isSPA.value ? Link : "a"; return ( @@ -67,7 +67,12 @@ export default component$(() => { Home Form About - Counters + console.log("visible")} + > + Counters +