Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/src/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 16 additions & 4 deletions docs/src/components/Navbar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { render, screen } from "@testing-library/react";
import type { ReactNode } from "react";
import { vi } from "vitest";
import logo from "../assets/logo.svg";
import { Navbar } from "./Navbar";

type MockNavbarProps = {
Expand All @@ -9,8 +10,8 @@ type MockNavbarProps = {
};

vi.mock("next/image", () => ({
default: ({ alt }: { alt?: string }) => (
<span data-testid="avatar" data-alt={alt} />
default: ({ alt, src }: { alt?: string; src?: string }) => (
<span data-testid="logo" data-alt={alt} data-src={src} />
),
}));

Expand Down Expand Up @@ -59,11 +60,22 @@ describe("Navbar", () => {
expect(home).toHaveTextContent("Worktree");
});

it("does not nest a link inside the logo and treats the avatar as decorative", () => {
it("does not nest a link inside the home link and treats the logo image as decorative", () => {
render(<Navbar />);

const home = screen.getByRole("link", { name: "Worktree home page" });
expect(home.querySelectorAll("a")).toHaveLength(0);
expect(screen.getByTestId("avatar")).toHaveAttribute("data-alt", "");
expect(screen.getByTestId("logo")).toHaveAttribute("data-alt", "");
});

it("renders the repository logo asset, not the organisation avatar", () => {
render(<Navbar />);

// Vitest inlines the SVG as a data URI where Next would give a hashed path;
// either way it must be an SVG, which rules out the avatar and a stringified
// StaticImageData object that would make the equality below vacuous.
const src = screen.getByTestId("logo").getAttribute("data-src");
expect(src).toMatch(/^data:image\/svg\+xml,|\.svg$/);
expect(src).toBe(String(logo));
});
});
17 changes: 4 additions & 13 deletions docs/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import Image from "next/image";
import Link from "next/link";
import { Navbar as NextraNavbar } from "nextra-theme-docs";
import {
projectLink,
projectName,
projectOwnerAvatarUrl,
} from "../lib/site-meta";
import logo from "../assets/logo.svg";
import { projectLink, projectName } from "../lib/site-meta";

// Nextra's own logo link is disabled (`logoLink={false}`) because its fixed
// aria-label "Home page" does not contain the visible text "Worktree" (WCAG
// 2.5.3). The logo is instead a next/link to "/", which applies the production
// basePath. The avatar is decorative (alt=""); the link's name starts with the
// basePath. The logo is decorative (alt=""); the link's name starts with the
// visible text and says where it goes. The utility classes are the ones
// Nextra's logo link uses, for the keyboard focus ring and hover affordance.
export function Navbar() {
Expand All @@ -29,13 +26,7 @@ export function Navbar() {
gap: "0.5rem",
}}
>
<Image
src={projectOwnerAvatarUrl}
alt=""
width={32}
height={32}
style={{ borderRadius: "999px" }}
/>
<Image src={logo} alt="" height={32} />
{projectName}
</Link>
}
Expand Down
Loading