From 7af1f59bb9b0b16397466ffcfc9c20d520da4eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 9 May 2026 16:49:34 +0200 Subject: [PATCH] fix(a11y): close violations the new e2e axe-core sweep surfaced MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five real WCAG 2.1 AA violations the extended axe-core spec caught: - top-bar.tsx: mobile user-menu DropdownMenuTrigger had no accessible name on viewports < sm (the username text is `hidden sm:inline`, leaving an icon-only button). Added aria-label using the existing nav.userMenu key. - password-input.tsx: show/hide eye toggle was icon-only, no aria-label. Added common.showPassword / common.hidePassword in en + de and bound to the visible state. - auth/login/page.tsx: "Sign up" link relied on colour alone (link-in-text-block). Switched hover:underline → underline so the link is distinguishable without colour. - page.tsx (dashboard): "Add" dropdown trigger was 32px tall (size="sm"); on Pixel 5 below WCAG 2.5.5 44px threshold. Added min-h-11 — desktop visual unchanged because the explicit height only kicks in if it exceeds the size variant's h-8. Co-Authored-By: Claude Opus 4.7 (1M context) --- messages/de.json | 4 +++- messages/en.json | 4 +++- src/app/auth/login/page.tsx | 7 ++++++- src/app/page.tsx | 6 +++++- src/components/layout/top-bar.tsx | 5 ++++- src/components/settings/password-input.tsx | 7 +++++++ 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/messages/de.json b/messages/de.json index a36eb32fe..80152dd7d 100644 --- a/messages/de.json +++ b/messages/de.json @@ -41,7 +41,9 @@ "copy": "Kopieren", "copyDetails": "Details kopieren", "retry": "Erneut versuchen", - "reportIssue": "Fehler melden" + "reportIssue": "Fehler melden", + "showPassword": "Passwort anzeigen", + "hidePassword": "Passwort verbergen" }, "doctorReport": { "title": "Gesundheitsbericht", diff --git a/messages/en.json b/messages/en.json index 4a7ad44e0..dfe3565dc 100644 --- a/messages/en.json +++ b/messages/en.json @@ -41,7 +41,9 @@ "copy": "Copy", "copyDetails": "Copy details", "retry": "Retry", - "reportIssue": "Report issue" + "reportIssue": "Report issue", + "showPassword": "Show password", + "hidePassword": "Hide password" }, "doctorReport": { "title": "Health Report", diff --git a/src/app/auth/login/page.tsx b/src/app/auth/login/page.tsx index befa9f494..ed1f25890 100644 --- a/src/app/auth/login/page.tsx +++ b/src/app/auth/login/page.tsx @@ -217,7 +217,12 @@ export default function LoginPage() { {t("auth.noAccount")}{" "} {t("auth.register")} diff --git a/src/app/page.tsx b/src/app/page.tsx index ca7a65257..116ff20bf 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -363,7 +363,11 @@ export default function DashboardPage() { - diff --git a/src/components/layout/top-bar.tsx b/src/components/layout/top-bar.tsx index 2bd3cc7f9..4bf0fa2fc 100644 --- a/src/components/layout/top-bar.tsx +++ b/src/components/layout/top-bar.tsx @@ -59,7 +59,10 @@ export function TopBar() {
) : user ? ( - + {user.username} diff --git a/src/components/settings/password-input.tsx b/src/components/settings/password-input.tsx index d4f915afb..0c44a1040 100644 --- a/src/components/settings/password-input.tsx +++ b/src/components/settings/password-input.tsx @@ -4,6 +4,7 @@ import { useState } from "react"; import { Eye, EyeOff } from "lucide-react"; import { Input } from "@/components/ui/input"; +import { useTranslations } from "@/lib/i18n/context"; /** * Password input with a built-in show/hide toggle. Extracted from the legacy @@ -13,12 +14,18 @@ import { Input } from "@/components/ui/input"; */ export function PasswordInput(props: React.ComponentProps) { const [visible, setVisible] = useState(false); + const { t } = useTranslations(); return (