From 4ef11901dbacb4662fb0b058c0c7561fe0768c4a Mon Sep 17 00:00:00 2001 From: npeter83 Date: Fri, 25 Sep 2026 17:21:01 +0200 Subject: [PATCH] fix(design): the nav rail's footer rows (language, About, Sign out) share the rail row and glyph (E28) --- frontend/src/components/LanguageSwitcher.tsx | 18 ++++++----- frontend/src/components/NavSidebar.tsx | 30 +++++++------------ .../src/components/ui/NavRail.dom.test.tsx | 21 ++++++++++++- frontend/src/components/ui/NavRail.tsx | 30 ++++++++++++++++++- 4 files changed, 71 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/LanguageSwitcher.tsx b/frontend/src/components/LanguageSwitcher.tsx index 51bb511c..e20db88b 100644 --- a/frontend/src/components/LanguageSwitcher.tsx +++ b/frontend/src/components/LanguageSwitcher.tsx @@ -4,6 +4,7 @@ import { LANGUAGES, type LangCode } from "../i18n"; import { PopoverItem, PopoverSurface } from "./ui/AnchoredPopover"; import { useAnchoredPopover } from "./ui/anchoredPopoverHooks"; import { Pressable } from "./ui/Pressable"; +import { RAIL_GLYPH, RAIL_ROW } from "./ui/NavRail"; import { SURFACE } from "./ui/surfaces"; // Compact language picker (globe + current code). Presentational: the parent decides what @@ -52,20 +53,23 @@ export default function LanguageSwitcher({ layer className={ rail - ? "relative p-2 rounded-lg text-muted hover:text-fg transition touch-target" + ? `${RAIL_ROW} h-9 text-muted hover:text-fg` : "flex h-7 items-center gap-1.5 px-2.5 rounded-lg text-sm text-muted hover:text-fg transition touch-target" } > - {rail ? ( - /* Current-language badge (HU/EN) so the active language reads at a glance without - opening the menu. The ring matches the page background to detach it from the icon. */ - - {current.code.toUpperCase()} + /* A rail row (F32), with the current-language badge (HU/EN) on the glyph's corner so the + active language reads at a glance. The ring matches the page to detach it from the icon. */ + + + + {current.code.toUpperCase()} + ) : ( - {current.code} + )} + {rail ? null : {current.code}} diff --git a/frontend/src/components/NavSidebar.tsx b/frontend/src/components/NavSidebar.tsx index 97288c0e..e0967a64 100644 --- a/frontend/src/components/NavSidebar.tsx +++ b/frontend/src/components/NavSidebar.tsx @@ -20,14 +20,20 @@ import { } from "../lib/modules"; import { useScrollFade } from "../lib/useScrollFade"; import { type LangCode } from "../i18n"; -import { IconButton } from "./ui/IconButton"; import AvatarImg from "./ui/Avatar"; import LanguageSwitcher from "./LanguageSwitcher"; import { PopoverSurface } from "./ui/AnchoredPopover"; import { useAnchoredPopover } from "./ui/anchoredPopoverHooks"; import { Pressable } from "./ui/Pressable"; import { SURFACE } from "./ui/surfaces"; -import { NavRail, NavRailDivider, NavRailItem, NavRailList, RAIL_ROW } from "./ui/NavRail"; +import { + NavRail, + NavRailAction, + NavRailDivider, + NavRailItem, + NavRailList, + RAIL_ROW, +} from "./ui/NavRail"; import { usePrefs } from "./prefsContext"; // Primary app navigation: a thin icon-only left rail. The modules used to hide under the avatar @@ -196,24 +202,10 @@ export default function NavSidebar({
-
+
- - - - - - + +
({ 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( {}} />); + 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(/]/); + }); +}); diff --git a/frontend/src/components/ui/NavRail.tsx b/frontend/src/components/ui/NavRail.tsx index 97fef293..f3c4c67b 100644 --- a/frontend/src/components/ui/NavRail.tsx +++ b/frontend/src/components/ui/NavRail.tsx @@ -62,6 +62,9 @@ export function NavRailDivider() { return
; } +/** 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({ /> )} -