"use client"; import type { MouseEvent, ReactNode } from "react"; import { prefersReducedMotion } from "@/lib/device"; import { elementForHash, focusFragment, isPlainPrimaryClick, } from "./cinematic/fragment-nav"; import { CONTACT_FORM_HASH, CONTACT_KIND_EVENT, CONTACT_KIND_PARAM, type ContactKind, contactKindHref, } from "./contact-subject"; import HoverPrefetchLink from "./HoverPrefetchLink"; /** * Deixa o endereço da home com o fragmento do cartão do formulário (`/#contact-form`) e sem o `?tipo=` que uma oferta * anterior ou a chegada de outra página deixou (o tipo já está no formulário). `replaceState`, e não uma navegação do * Next: nada recarrega, e as âncoras seguintes (cabeçalho, rodapé) continuam a rolar a página. */ function showContactInAddress() { const url = new URL(window.location.href); url.searchParams.delete(CONTACT_KIND_PARAM); url.hash = CONTACT_FORM_HASH; const next = `${url.pathname}${url.search}${url.hash}`; const current = `${window.location.pathname}${window.location.search}${window.location.hash}`; if (next !== current) window.history.replaceState(window.history.state, "", next); } /** * Botão de uma oferta da home: leva ao cartão do formulário de contato (`#contact-form`, com o campo do tipo de projeto * à vista, também no celular) com o tipo já escolhido. Na própria home o tipo segue por evento e a página rola até o * cartão (sem navegar pelo Next); o `href` com `?tipo=` cobre quem chega de outra página ou abre o link em outra aba. * * O normal é o gerenciador de âncoras (fragment-nav + useCinematicScroll) tratar o clique antes deste código, do * mesmo jeito que trata o link do cabeçalho: rola (com movimento reduzido, em salto), dá o foco ao formulário e * cancela o clique. Quando ele não o trata (ainda não montou, por exemplo), este botão cancela a navegação, rola e dá * o foco por conta própria. Em outra página, nada é cancelado: o Link navega para `/?tipo=…#contact-form`. */ export default function ContactOfferLink({ kind, className, children, }: { kind: ContactKind; className?: string; children: ReactNode; }) { const onClick = (event: MouseEvent) => { window.dispatchEvent( new CustomEvent(CONTACT_KIND_EVENT, { detail: kind }), ); if (window.location.pathname !== "/") return; const form = elementForHash(CONTACT_FORM_HASH); if (!form) return; if (event.defaultPrevented) { showContactInAddress(); return; } // aba nova, clique com tecla modificadora ou botão do meio: o navegador cuida, com o `?tipo=` do href if (!isPlainPrimaryClick(event.nativeEvent)) return; event.preventDefault(); showContactInAddress(); form.scrollIntoView({ behavior: prefersReducedMotion() ? "instant" : "smooth", block: "start", }); focusFragment(form); }; return ( {children} ); }