feat(cases): prova certa por serviço, páginas internas com trabalho no topo

Diagnóstico sem case que não cabe; desktop com o GCC Installer como projeto próprio; IoT com o Twins Lab e a nota da Apolo. Mosaico de pôsteres em /servicos e /cases, faixa baixa em uma coluna no currículo, privacidade e laboratório; Laboratório como lista compacta; SEV começando por catálogo, pedido no WhatsApp e painel; Joinville e SC nos títulos; imagens do LCP com fetchPriority e sizes reais; pré-carregamento só no hover; 404 com Open Graph próprio.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 17:01:35 -03:00
1 parent 7b633f0f4a
commit de6af74a0c
37 files changed
+1062 -254

No files matched your search

@@ -0,0 +1,52 @@
import { fireEvent, render, screen } from "@testing-library/react";
import { Breadcrumb } from "./Breadcrumb";
/**
* A trilha de navegação só pré-carrega a rota de um item quando a pessoa chega nele (mouse, teclado ou toque):
* o `prefetch` não aparece no HTML, então o Link é trocado por um que o expõe em `data-prefetch`.
*/
jest.mock("next/link", () => ({
__esModule: true,
default: ({
children,
prefetch,
...props
}: { children?: React.ReactNode; prefetch?: boolean | null } & Record<
string,
unknown
>) => (
<a data-prefetch={String(prefetch)} {...props}>
{children}
</a>
),
}));
const items = [
{ label: "Início", href: "/" },
{ label: "Cases", href: "/cases" },
];
describe("Breadcrumb: pré-carregamento", () => {
it("path: opening the page -> no link pre-fetches", () => {
render(<Breadcrumb items={items} />);
for (const link of screen.getAllByRole("link")) {
expect(link).toHaveAttribute("data-prefetch", "false");
}
});
it.each([
["mouse", fireEvent.mouseEnter],
["keyboard focus", fireEvent.focus],
["touch", fireEvent.touchStart],
])("path: %s reaching one link -> only that link pre-fetches", (_, event) => {
render(<Breadcrumb items={items} />);
const [home, cases] = screen.getAllByRole("link");
event(cases);
expect(cases).toHaveAttribute("data-prefetch", "null");
expect(home).toHaveAttribute("data-prefetch", "false");
});
});
+7 -4
View File
@@ -1,6 +1,9 @@
import Link from "next/link";
import HoverPrefetchLink from "./HoverPrefetchLink";
/** Trilha de navegação sobre fundo escuro, no topo das páginas internas. O último item é a página atual. */
/**
* Trilha de navegação sobre fundo escuro, no topo das páginas internas. O último item é a página atual.
* Os links só pré-carregam a rota quando a pessoa chega neles (HoverPrefetchLink).
*/
export function Breadcrumb({
items,
}: {
@@ -15,13 +18,13 @@ export function Breadcrumb({
className={index > 0 ? "flex items-center gap-sp-2" : undefined}
>
{index > 0 ? <span aria-hidden="true">/</span> : null}
<Link
<HoverPrefetchLink
aria-current={index === items.length - 1 ? "page" : undefined}
className="ds-link ds-link-text"
href={href}
>
{label}
</Link>
</HoverPrefetchLink>
</li>
))}
</ol>