Rot-Dialog: Rollbarkeit bei vielen Stapeln und echte Modalität
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.
This commit is contained in:
+3
-1
@@ -88,11 +88,13 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: safe center;
|
||||||
gap: 18px;
|
gap: 18px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay.green { background: var(--green); }
|
.overlay.green { background: var(--green); }
|
||||||
|
|||||||
@@ -38,6 +38,21 @@ export function askForStack(root, { spec, candidates }) {
|
|||||||
overlay.querySelector('#read').textContent = describeReading(spec);
|
overlay.querySelector('#read').textContent = describeReading(spec);
|
||||||
|
|
||||||
const choices = overlay.querySelector('#choices');
|
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);
|
root.appendChild(overlay);
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
@@ -48,6 +63,20 @@ export function askForStack(root, { spec, candidates }) {
|
|||||||
if (settled) return;
|
if (settled) return;
|
||||||
settled = true;
|
settled = true;
|
||||||
overlay.remove();
|
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);
|
resolve(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user