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
This commit is contained in:
Sorin Davidoi 2018-02-15 00:37:19 +01:00 committed by Michael Bryan
parent 89a5dbaf9a
commit d306aed587
2 changed files with 35 additions and 9 deletions

View File

@ -298,11 +298,13 @@ function playpen_text(playpen) {
function showThemes() { function showThemes() {
themePopup.style.display = 'block'; themePopup.style.display = 'block';
themeToggleButton.setAttribute('aria-expanded', true); themeToggleButton.setAttribute('aria-expanded', true);
themePopup.querySelector("button#" + document.body.className).focus();
} }
function hideThemes() { function hideThemes() {
themePopup.style.display = 'none'; themePopup.style.display = 'none';
themeToggleButton.setAttribute('aria-expanded', false); themeToggleButton.setAttribute('aria-expanded', false);
themeToggleButton.focus();
} }
function set_theme(theme) { function set_theme(theme) {
@ -369,19 +371,43 @@ function playpen_text(playpen) {
set_theme(theme); set_theme(theme);
}); });
// Hide theme selector popup when clicking outside of it themePopup.addEventListener('focusout', function(e) {
document.addEventListener('click', function (event) { if (!themePopup.contains(e.relatedTarget)) {
if (themePopup.style.display === 'block' && !themeToggleButton.contains(event.target) && !themePopup.contains(event.target)) {
hideThemes(); hideThemes();
} }
}); });
document.addEventListener('keydown', function (e) { document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (!themePopup.contains(e.target)) { return; }
switch (e.key) { switch (e.key) {
case 'Escape': case 'Escape':
e.preventDefault(); e.preventDefault();
hideThemes(); hideThemes();
break; break;
case 'ArrowUp':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.previousElementSibling) {
li.previousElementSibling.querySelector('button').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.nextElementSibling) {
li.nextElementSibling.querySelector('button').focus();
}
break;
case 'Home':
e.preventDefault();
themePopup.querySelector('li:first-child button').focus();
break;
case 'End':
e.preventDefault();
themePopup.querySelector('li:last-child button').focus();
break;
} }
}); });
})(); })();

View File

@ -95,12 +95,12 @@
<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"> <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">
<i class="fa fa-paint-brush"></i> <i class="fa fa-paint-brush"></i>
</button> </button>
<ul id="theme-list" class="theme-popup" aria-label="submenu"> <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li><button class="theme" id="light">Light <span class="default">(default)</span></button></li> <li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
<li><button class="theme" id="rust">Rust</button></li> <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li><button class="theme" id="coal">Coal</button></li> <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li><button class="theme" id="navy">Navy</button></li> <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li><button class="theme" id="ayu">Ayu</button></li> <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul> </ul>
</div> </div>