fix(design): the nav rail's footer rows (language, About, Sign out) share the rail row and glyph (E28)
This commit is contained in:
@@ -3,10 +3,12 @@
|
||||
// E28 S3d (B7): the nav rail's row. Icon-only, its name is the module's full name (with an unread
|
||||
// count, which was only ever drawn); with the labels on, the name is the short label the user SEES
|
||||
// (WCAG 2.5.3), the full one staying in the tooltip. "You are here" is aria-current plus the tint.
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import { Bell } from "lucide-react";
|
||||
import { NavRailItem } from "./NavRail";
|
||||
import { NavRailAction, NavRailItem } from "./NavRail";
|
||||
|
||||
vi.mock("../../lib/hints", () => ({ hintsEnabled: () => true, subscribeHints: () => () => {} }));
|
||||
|
||||
@@ -45,3 +47,20 @@ describe("NavRailItem", () => {
|
||||
expect(row.getAttribute("aria-current")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// F32: the rail's footer (language, About, Sign out) drew 32 and 36 squares with 16 and 20px glyphs
|
||||
// beside the 36-tall full-width rows, so its spacing and glyphs broke the column. An action is a row too.
|
||||
describe("NavRailAction", () => {
|
||||
it("is a named rail row, not a toolbar icon button", () => {
|
||||
render(<NavRailAction icon={Bell} label="About" onClick={() => {}} />);
|
||||
const row = screen.getByRole("button", { name: "About" });
|
||||
expect(row.className).toContain("h-9");
|
||||
expect(row.className).toContain("w-full");
|
||||
expect(row.querySelector("svg")?.getAttribute("class")).toContain("size-4.5");
|
||||
});
|
||||
|
||||
it("the nav rail holds no toolbar icon button", () => {
|
||||
const src = readFileSync(resolve(__dirname, "../NavSidebar.tsx"), "utf8");
|
||||
expect(src).not.toMatch(/<IconButton[\s>]/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -62,6 +62,9 @@ export function NavRailDivider() {
|
||||
return <div className="mx-auto my-1.5 w-7 shrink-0 border-t-2 border-border" />;
|
||||
}
|
||||
|
||||
/** The glyph of every rail row: a page, an action, the language switcher. */
|
||||
export const RAIL_GLYPH = "size-4.5";
|
||||
|
||||
/** The shape of one rail row, for a row that is not a page (the account button). */
|
||||
export const RAIL_ROW =
|
||||
"relative flex w-full flex-col items-center justify-center gap-0.5 rounded-lg transition touch-target";
|
||||
@@ -112,7 +115,7 @@ export function NavRailItem({
|
||||
/>
|
||||
)}
|
||||
<span className="relative shrink-0">
|
||||
<Icon className="size-4.5" aria-hidden="true" />
|
||||
<Icon className={RAIL_GLYPH} aria-hidden="true" />
|
||||
{shown && (
|
||||
<span className="absolute -top-2 -right-2 grid h-4 min-w-4 place-items-center rounded-full bg-accent px-1 text-3xs leading-none font-bold text-accent-fg ring-2 ring-bg">
|
||||
{badge > 9 ? "9+" : badge}
|
||||
@@ -128,3 +131,28 @@ export function NavRailItem({
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
/** A rail row that acts instead of navigating (About, Sign out): the page rows' geometry and glyph, so
|
||||
* the column keeps one rhythm (F32: toolbar icon buttons here drew 32 squares with 16px glyphs). */
|
||||
export function NavRailAction({
|
||||
icon: Icon,
|
||||
label,
|
||||
onClick,
|
||||
}: {
|
||||
icon: LucideIcon;
|
||||
/** The tooltip and the accessible name. */
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}) {
|
||||
return (
|
||||
<Tooltip hint={label} side="right" always openDelay={350}>
|
||||
<Pressable
|
||||
onClick={onClick}
|
||||
aria-label={label}
|
||||
className={clsx(RAIL_ROW, "h-9 text-muted state-layer hover:text-fg")}
|
||||
>
|
||||
<Icon className={RAIL_GLYPH} aria-hidden="true" />
|
||||
</Pressable>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user