Files
portifolio-evandrodevbr/app/components/HoverPrefetchLink.tsx
T
Evandro Fonseca Junior 9e2d65a926 fix(home): oferta leva ao formulário, ofertas logo depois da vitrine
O botão das ofertas rola até o contato com o tipo marcado e não quebra mais as âncoras; ofertas com o que você recebe e primeiro passo, logo depois da vitrine; bloco de IA fora da home; cartão largo da SEV no hero do celular; separador da faixa de clientes só entre itens; favicon de 13 para 1,8 KB; pré-carregamento só no hover e nunca de /#... fora da home; X do menu e cabeçalho opaco; WhatsApp com "o case"; /ia com 3 passos e modelo de relatório ilustrativo; Sobre alinhado ao currículo; CSP Report-Only com os domínios do Ads.
2026-10-14 19:14:47 -03:00

63 lines
2.4 KiB
TypeScript

"use client";
import Link from "next/link";
import * as navigation from "next/navigation";
import { type ComponentProps, useState } from "react";
type LinkHref = ComponentProps<typeof Link>["href"];
/**
* O caminho da página aberta. Sem `usePathname` (testes que trocam next/navigation por um dublê só com
* `notFound`, por exemplo) vale `null`: sem caminho conhecido, nada muda no pré-carregamento.
*/
const usePathname: () => string | null = navigation.usePathname ?? (() => null);
/** Link para um ponto da home: `/#contact` ou `/?tipo=site#contact`. */
function isHomeAnchor(href: LinkHref) {
if (typeof href === "string") return /^\/(\?[^#]*)?#/.test(href);
return href.pathname === "/" && Boolean(href.hash);
}
/**
* Link interno que só pré-carrega a rota quando a pessoa chega nele (mouse, teclado ou toque).
* O padrão do Link pré-carrega todo link visível ao abrir a página, e o cabeçalho e a faixa de clientes
* somavam 15 pedidos disputando a rede na abertura. Com `prefetch={false}` o App Router não pré-carrega nem no hover.
* Padrão da documentação do Next: node_modules/next/dist/docs/01-app/02-guides/prefetching.md.
*
* Fora da home, um link para um ponto dela (`/#contact`) não pré-carrega nem no hover: o pré-carregamento puxaria
* a home inteira, com o CSS da vitrine, para quem só passou o mouse (e o navegador avisava "preloaded but not
* used"). Na própria home o link leva à página em que a pessoa já está, e o pré-carregamento segue o padrão. O
* caminho vem de `usePathname`, e não de uma leitura única no hover: o cabeçalho e o rodapé não remontam entre as
* páginas, e um link ativado na home não pode continuar pré-carregando depois que a pessoa sair dela.
*/
export default function HoverPrefetchLink({
onMouseEnter,
onFocus,
onTouchStart,
...props
}: Omit<ComponentProps<typeof Link>, "prefetch">) {
const pathname = usePathname();
const [active, setActive] = useState(false);
const homeAnchorFromElsewhere =
pathname !== null && pathname !== "/" && isHomeAnchor(props.href);
return (
<Link
{...props}
prefetch={active && !homeAnchorFromElsewhere ? null : false}
onMouseEnter={(event) => {
setActive(true);
onMouseEnter?.(event);
}}
onFocus={(event) => {
setActive(true);
onFocus?.(event);
}}
onTouchStart={(event) => {
setActive(true);
onTouchStart?.(event);
}}
/>
);
}