From 0c96743211b4a769d3d5f2fae083941d497c5f9b Mon Sep 17 00:00:00 2001 From: vchuser Date: Tue, 28 Jul 2026 17:20:19 +0200 Subject: [PATCH] =?UTF-8?q?Rot-Dialog:=20Rollbarkeit=20bei=20vielen=20Stap?= =?UTF-8?q?eln=20und=20echte=20Modalit=C3=A4t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beanstandung 1: .overlay bekommt overflow-y:auto, overscroll-behavior: contain und justify-content:safe center, damit bei vielen Kandidaten- Stapeln (Rot-Fall bietet alle Stapel der Sitzung an) keine Schaltfläche mehr unerreichbar aus dem Bildschirm waechst, ohne dass die Seite dahinter mitrollt oder sich die Optik bei wenigen Stapeln aendert. Beanstandung 2: askForStack setzt inert auf die Geschwisterelemente von root, solange der Dialog offen ist, und hebt es beim Schliessen (ueber jeden der drei Wege) nur fuer selbst gesetzte Elemente wieder auf. Fokus kehrt nach dem Schliessen zum vorherigen Element zurueck statt auf dem entfernten Dialog haengen zu bleiben. --- src/styles.css | 4 +++- src/ui/ambiguous-dialog.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/styles.css b/src/styles.css index 65ff1e3..3f268de 100644 --- a/src/styles.css +++ b/src/styles.css @@ -88,11 +88,13 @@ body { display: flex; flex-direction: column; align-items: center; - justify-content: center; + justify-content: safe center; gap: 18px; padding: 24px; text-align: center; z-index: 10; + overflow-y: auto; + overscroll-behavior: contain; } .overlay.green { background: var(--green); } diff --git a/src/ui/ambiguous-dialog.js b/src/ui/ambiguous-dialog.js index eeadd8f..761c039 100644 --- a/src/ui/ambiguous-dialog.js +++ b/src/ui/ambiguous-dialog.js @@ -38,6 +38,21 @@ export function askForStack(root, { spec, candidates }) { overlay.querySelector('#read').textContent = describeReading(spec); const choices = overlay.querySelector('#choices'); + + // Waehrend der Dialog offen ist, muss die Modalitaet, die per aria-modal + // behauptet wird, auch durchgesetzt werden: die Geschwisterelemente im + // Wurzelelement werden per inert unerreichbar (Tastatur, Zeigegeraet, + // Hilfsmittel). Elemente, die schon vorher inert waren, bleiben es - + // nur die selbst gesetzten inert-Markierungen werden spaeter entfernt. + const previouslyFocused = document.activeElement; + const madeInert = []; + for (const sibling of root.children) { + if (!sibling.hasAttribute('inert')) { + sibling.setAttribute('inert', ''); + madeInert.push(sibling); + } + } + root.appendChild(overlay); return new Promise((resolve) => { @@ -48,6 +63,20 @@ export function askForStack(root, { spec, candidates }) { if (settled) return; settled = true; overlay.remove(); + for (const sibling of madeInert) { + sibling.removeAttribute('inert'); + } + // Fokus darf nicht auf dem entfernten Dialog-Element haengen bleiben - + // zurueck zu dem, was vorher den Fokus hatte, sofern das noch moeglich ist. + if ( + previouslyFocused && + typeof previouslyFocused.focus === 'function' && + document.contains(previouslyFocused) + ) { + previouslyFocused.focus(); + } else { + root.focus?.(); + } resolve(result); };