fix(ui): give the shared product-link class a focus ring

Docs went from a ghost Button to a plain anchor, which dropped the focus
treatment the Button was supplying, so tabbing to Docs showed nothing while
tabbing to Blog showed a ring. The ring now lives on the shared class both
sides use, matching the Button primitive's values.

Kept Docs as a real anchor rather than routing it back through Button:
nativeButton={false} stamps role="button" onto the element, so the old
DashboardHeader markup announced Docs as a button and lost its link
semantics. Tests pin both the ring and the link role.
This commit is contained in:
ryan-crabbe-berri 2026-08-27 20:50:41 -07:00
parent e5dcc6873e
commit 929946bdc1
3 changed files with 22 additions and 4 deletions

View file

@ -24,4 +24,19 @@ describe("DocsLink", () => {
}
expect(link).not.toHaveClass("text-muted-foreground");
});
it("carries a focus ring, so tabbing to Docs looks like tabbing to Blog", () => {
render(<DocsLink />);
const link = screen.getByRole("link", { name: "Docs" });
expect(link).toHaveClass("focus-visible:ring-3");
expect(link).toHaveClass("focus-visible:ring-ring/50");
});
it("stays a link rather than being relabelled as a button by the Button primitive", () => {
render(<DocsLink />);
expect(screen.getByRole("link", { name: "Docs" })).toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Docs" })).not.toBeInTheDocument();
});
});

View file

@ -4,11 +4,14 @@ import React from "react";
export const DOCS_URL = "https://docs.litellm.ai/docs/";
const ChevronWidthSpacer: React.FC = () => (
<ChevronDown className="pointer-events-none size-2.5 opacity-0" aria-hidden />
);
export const DocsLink: React.FC = () => (
<a href={DOCS_URL} target="_blank" rel="noopener noreferrer" className={NAV_PRODUCT_LINK_CLASS}>
Docs
{/* Docs is a single outbound link; the hidden chevron keeps its box identical to the Blog dropdown trigger. */}
<ChevronDown className="pointer-events-none size-2.5 opacity-0" aria-hidden />
<ChevronWidthSpacer />
</a>
);

View file

@ -1,3 +1,3 @@
/** Shared styling for Docs / Blog in the top nav (product navigation zone). */
/** Shared styling for Docs / Blog in the top nav (product navigation zone). Focus ring matches the Button primitive. */
export const NAV_PRODUCT_LINK_CLASS =
"inline-flex h-9 shrink-0 items-center justify-center gap-1 rounded-md px-2 text-sm font-medium leading-none text-foreground transition-colors hover:bg-accent ";
"inline-flex h-9 shrink-0 items-center justify-center gap-1 rounded-md px-2 text-sm font-medium leading-none text-foreground outline-none transition-colors hover:bg-accent focus-visible:ring-3 focus-visible:ring-ring/50 ";