Skip to content

Commit d306aed

Browse files
sorin-davidoiMichael-F-Bryan
authored andcommitted
Accessibility improvements (#611)
* fix(theme/book/themes): Check for control keys in event listener * fix(theme/index): Menu role for theme selector * fix(theme/book/themes): Handle focus when toggling theme list * feat(theme/book/themes): Handle ArrowUp, ArrowDown, Home and End
1 parent 89a5dba commit d306aed

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

src/theme/book.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,13 @@ function playpen_text(playpen) {
298298
function showThemes() {
299299
themePopup.style.display = 'block';
300300
themeToggleButton.setAttribute('aria-expanded', true);
301+
themePopup.querySelector("button#" + document.body.className).focus();
301302
}
302303

303304
function hideThemes() {
304305
themePopup.style.display = 'none';
305306
themeToggleButton.setAttribute('aria-expanded', false);
307+
themeToggleButton.focus();
306308
}
307309

308310
function set_theme(theme) {
@@ -369,19 +371,43 @@ function playpen_text(playpen) {
369371
set_theme(theme);
370372
});
371373

372-
// Hide theme selector popup when clicking outside of it
373-
document.addEventListener('click', function (event) {
374-
if (themePopup.style.display === 'block' && !themeToggleButton.contains(event.target) && !themePopup.contains(event.target)) {
374+
themePopup.addEventListener('focusout', function(e) {
375+
if (!themePopup.contains(e.relatedTarget)) {
375376
hideThemes();
376377
}
377378
});
378379

379380
document.addEventListener('keydown', function (e) {
381+
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
382+
if (!themePopup.contains(e.target)) { return; }
383+
380384
switch (e.key) {
381385
case 'Escape':
382386
e.preventDefault();
383387
hideThemes();
384388
break;
389+
case 'ArrowUp':
390+
e.preventDefault();
391+
var li = document.activeElement.parentElement;
392+
if (li && li.previousElementSibling) {
393+
li.previousElementSibling.querySelector('button').focus();
394+
}
395+
break;
396+
case 'ArrowDown':
397+
e.preventDefault();
398+
var li = document.activeElement.parentElement;
399+
if (li && li.nextElementSibling) {
400+
li.nextElementSibling.querySelector('button').focus();
401+
}
402+
break;
403+
case 'Home':
404+
e.preventDefault();
405+
themePopup.querySelector('li:first-child button').focus();
406+
break;
407+
case 'End':
408+
e.preventDefault();
409+
themePopup.querySelector('li:last-child button').focus();
410+
break;
385411
}
386412
});
387413
})();

src/theme/index.hbs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@
9595
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
9696
<i class="fa fa-paint-brush"></i>
9797
</button>
98-
<ul id="theme-list" class="theme-popup" aria-label="submenu">
99-
<li><button class="theme" id="light">Light <span class="default">(default)</span></button></li>
100-
<li><button class="theme" id="rust">Rust</button></li>
101-
<li><button class="theme" id="coal">Coal</button></li>
102-
<li><button class="theme" id="navy">Navy</button></li>
103-
<li><button class="theme" id="ayu">Ayu</button></li>
98+
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
99+
<li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
100+
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
101+
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
102+
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
103+
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
104104
</ul>
105105
</div>
106106

0 commit comments

Comments
 (0)