From c608f06806af9e0f67ca57ec8dbbc765cdad6bf6 Mon Sep 17 00:00:00 2001 From: patrick Date: Mon, 7 Sep 2026 23:30:01 +0200 Subject: [PATCH] fix(a11y): Kontroll-UI - Touch-Targets, Labels, Live-Regions, Dialog-Semantik MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 44px-Mindestgröße für Buttons/Inputs (Feldeinsatz mit Handschuhen), echte Label-Verknüpfung statt reinem placeholder auf allen Kontroll-Eingabefeldern, aria-live-Statusansagen beim Speichern/Fehler einer Position und beim Öffnen des Nachfüll-Dialogs, NachfuellDialog jetzt mit role="dialog"/aria-modal, Fokus beim Öffnen und Esc zum Schließen, Pflichtfeld Begründung mit aria-required. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV --- frontend/src/pages/KontrollPage.tsx | 27 ++++++++------ .../src/pages/kontrolle/NachfuellDialog.tsx | 36 +++++++++++++++++-- frontend/src/pages/kontrolle/PositionCard.tsx | 35 ++++++++++++++++-- frontend/src/styles/global.css | 19 +++++++++- 4 files changed, 100 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/KontrollPage.tsx b/frontend/src/pages/KontrollPage.tsx index eb0df09..861e8ee 100644 --- a/frontend/src/pages/KontrollPage.tsx +++ b/frontend/src/pages/KontrollPage.tsx @@ -111,17 +111,22 @@ export function KontrollPage() { onErneutVersuchen={fehlerErneutVersuchen} /> {nachfuellDialog?.materialId === zustand.position.material_id && ( - jetztNachfuellen(nachfuellDialog.fehlbestandId, menge)} - onMindermengeGenehmigen={(begruendung) => - jetztMindermengeGenehmigen(nachfuellDialog.fehlbestandId, begruendung) - } - onSchliessen={nachfuellDialogSchliessen} - /> + <> + + Fehlmenge bei {zustand.material?.name ?? "Material"} – Dialog geöffnet. + + jetztNachfuellen(nachfuellDialog.fehlbestandId, menge)} + onMindermengeGenehmigen={(begruendung) => + jetztMindermengeGenehmigen(nachfuellDialog.fehlbestandId, begruendung) + } + onSchliessen={nachfuellDialogSchliessen} + /> + )} ))} diff --git a/frontend/src/pages/kontrolle/NachfuellDialog.tsx b/frontend/src/pages/kontrolle/NachfuellDialog.tsx index b7d8d56..a92e6ed 100644 --- a/frontend/src/pages/kontrolle/NachfuellDialog.tsx +++ b/frontend/src/pages/kontrolle/NachfuellDialog.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { useAuth } from "../../auth/AuthContext"; @@ -24,14 +24,38 @@ export function NachfuellDialog({ const [menge, setMenge] = useState(vorschlagMenge); const [mindermengeOffen, setMindermengeOffen] = useState(false); const [begruendung, setBegruendung] = useState(""); + const mengeRef = useRef(null); + const titelId = "nachfuell-dialog-titel"; + + // Fokus beim Öffnen in den Dialog, Esc schließt ihn - ohne das erwartet ein + // Tastatur-/Screenreader-Nutzer keinen neuen interaktiven Bereich. + useEffect(() => { + mengeRef.current?.focus(); + function taste(e: KeyboardEvent) { + if (e.key === "Escape") onSchliessen(); + } + document.addEventListener("keydown", taste); + return () => document.removeEventListener("keydown", taste); + }, [onSchliessen]); return ( -
-
+
+
Fehlmenge bei {materialName} – jetzt aus Lager nachfüllen?
+ {mindermengeOffen && (
+ setBegruendung(e.target.value)} + required + aria-required="true" />