a11y(dialog): ARIA-Rolle, Fokus-Falle und Fokus-Rueckgabe ergaenzt ohne Escape/Initial-Fokus zu doppeln
This commit is contained in:
@@ -40,23 +40,30 @@ const HellionDialog = {
|
|||||||
*/
|
*/
|
||||||
_show(config) {
|
_show(config) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
const prevFocus = document.activeElement;
|
||||||
const overlay = document.createElement('div');
|
const overlay = document.createElement('div');
|
||||||
overlay.className = 'dialog-overlay';
|
overlay.className = 'dialog-overlay';
|
||||||
|
|
||||||
const box = document.createElement('div');
|
const box = document.createElement('div');
|
||||||
box.className = 'dialog-box';
|
box.className = 'dialog-box';
|
||||||
|
box.setAttribute('role', config.isConfirm ? 'alertdialog' : 'dialog');
|
||||||
|
box.setAttribute('aria-modal', 'true');
|
||||||
|
box.setAttribute('aria-labelledby', 'dialogTitle');
|
||||||
|
box.setAttribute('aria-describedby', 'dialogBody');
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
const header = document.createElement('div');
|
const header = document.createElement('div');
|
||||||
header.className = 'dialog-header';
|
header.className = 'dialog-header';
|
||||||
header.appendChild(this._createIcon(config.type));
|
header.appendChild(this._createIcon(config.type));
|
||||||
const titleSpan = document.createElement('span');
|
const titleSpan = document.createElement('span');
|
||||||
|
titleSpan.id = 'dialogTitle';
|
||||||
titleSpan.textContent = config.title;
|
titleSpan.textContent = config.title;
|
||||||
header.appendChild(titleSpan);
|
header.appendChild(titleSpan);
|
||||||
|
|
||||||
// Body
|
// Body
|
||||||
const body = document.createElement('div');
|
const body = document.createElement('div');
|
||||||
body.className = 'dialog-body';
|
body.className = 'dialog-body';
|
||||||
|
body.id = 'dialogBody';
|
||||||
body.textContent = config.message;
|
body.textContent = config.message;
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
@@ -69,6 +76,7 @@ const HellionDialog = {
|
|||||||
overlay.classList.remove('active');
|
overlay.classList.remove('active');
|
||||||
overlay.remove();
|
overlay.remove();
|
||||||
});
|
});
|
||||||
|
if (prevFocus && typeof prevFocus.focus === 'function') prevFocus.focus();
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +114,18 @@ const HellionDialog = {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
cleanup(config.isConfirm ? false : undefined);
|
cleanup(config.isConfirm ? false : undefined);
|
||||||
}
|
}
|
||||||
|
if (e.key === 'Tab') {
|
||||||
|
// Fokus-Falle: nur die Buttons im actions-Container sind fokussierbar
|
||||||
|
const items = Array.from(actions.querySelectorAll('button'));
|
||||||
|
if (items.length === 0) return;
|
||||||
|
const first = items[0];
|
||||||
|
const last = items[items.length - 1];
|
||||||
|
if (e.shiftKey && document.activeElement === first) {
|
||||||
|
e.preventDefault(); last.focus();
|
||||||
|
} else if (!e.shiftKey && document.activeElement === last) {
|
||||||
|
e.preventDefault(); first.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
document.addEventListener('keydown', keyHandler);
|
document.addEventListener('keydown', keyHandler);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user