doc: improve accessibility of expandable lists

PR-URL: https://github.com/nodejs/node/pull/56749
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
Reviewed-By: Claudio Wunder <cwunder@gnome.org>
This commit is contained in:
Antoine du Hamel 2025-01-26 19:31:35 +01:00 committed by GitHub
parent ea7ab162d6
commit a6c5ce27d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 20 additions and 21 deletions

View File

@ -41,6 +41,7 @@
function closeAllPickers() { function closeAllPickers() {
for (const picker of pickers) { for (const picker of pickers) {
picker.parentNode.classList.remove('expanded'); picker.parentNode.classList.remove('expanded');
picker.ariaExpanded = false;
} }
window.removeEventListener('click', closeAllPickers); window.removeEventListener('click', closeAllPickers);
@ -58,6 +59,7 @@
for (const picker of pickers) { for (const picker of pickers) {
const parentNode = picker.parentNode; const parentNode = picker.parentNode;
picker.ariaExpanded = parentNode.classList.contains('expanded');
picker.addEventListener('click', function(e) { picker.addEventListener('click', function(e) {
e.preventDefault(); e.preventDefault();
@ -65,7 +67,7 @@
closeAllPickers as window event trigger already closed all the pickers, closeAllPickers as window event trigger already closed all the pickers,
if it already closed there is nothing else to do here if it already closed there is nothing else to do here
*/ */
if (parentNode.classList.contains('expanded')) { if (picker.ariaExpanded === 'true') {
return; return;
} }
@ -75,9 +77,11 @@
*/ */
requestAnimationFrame(function() { requestAnimationFrame(function() {
picker.ariaExpanded = true;
parentNode.classList.add('expanded'); parentNode.classList.add('expanded');
window.addEventListener('click', closeAllPickers); window.addEventListener('click', closeAllPickers);
window.addEventListener('keydown', onKeyDown); window.addEventListener('keydown', onKeyDown);
parentNode.querySelector('.picker a').focus();
}); });
}); });
} }

View File

@ -182,22 +182,15 @@ li.picker-header .picker-arrow {
height: .6rem; height: .6rem;
border-top: .3rem solid transparent; border-top: .3rem solid transparent;
border-bottom: .3rem solid transparent; border-bottom: .3rem solid transparent;
border-left: .6rem solid var(--color-links); border-left: .6rem solid currentColor;
border-right: none; border-right: none;
margin: 0 .2rem .05rem 0; margin: 0 .2rem .05rem 0;
} }
li.picker-header a:focus .picker-arrow, li.picker-header.expanded .picker-arrow,
li.picker-header a:active .picker-arrow, :root:not(.has-js) li.picker-header:focus-within .picker-arrow,
li.picker-header a:hover .picker-arrow {
border-left: .6rem solid var(--white);
}
li.picker-header.expanded a:focus .picker-arrow,
li.picker-header.expanded a:active .picker-arrow,
li.picker-header.expanded a:hover .picker-arrow,
:root:not(.has-js) li.picker-header:hover .picker-arrow { :root:not(.has-js) li.picker-header:hover .picker-arrow {
border-top: .6rem solid var(--white); border-top: .6rem solid currentColor;
border-bottom: none; border-bottom: none;
border-left: .35rem solid transparent; border-left: .35rem solid transparent;
border-right: .35rem solid transparent; border-right: .35rem solid transparent;
@ -205,11 +198,13 @@ li.picker-header.expanded a:hover .picker-arrow,
} }
li.picker-header.expanded > a, li.picker-header.expanded > a,
:root:not(.has-js) li.picker-header:focus-within > a,
:root:not(.has-js) li.picker-header:hover > a { :root:not(.has-js) li.picker-header:hover > a {
border-radius: 2px 2px 0 0; border-radius: 2px 2px 0 0;
} }
li.picker-header.expanded > .picker, li.picker-header.expanded > .picker,
:root:not(.has-js) li.picker-header:focus-within > .picker,
:root:not(.has-js) li.picker-header:hover > .picker { :root:not(.has-js) li.picker-header:hover > .picker {
display: block; display: block;
z-index: 1; z-index: 1;

View File

@ -59,13 +59,13 @@
__GTOC_PICKER__ __GTOC_PICKER__
__ALTDOCS__ __ALTDOCS__
<li class="picker-header"> <li class="picker-header">
<a href="#"> <a href="#options-picker" aria-controls="options-picker">
<span class="picker-arrow"></span> <span class="picker-arrow"></span>
Options Options
</a> </a>
<div class="picker"> <div class="picker" tabindex="-1">
<ul> <ul id="options-picker">
<li> <li>
<a href="all.html">View on single page</a> <a href="all.html">View on single page</a>
</li> </li>

View File

@ -527,11 +527,11 @@ function altDocs(filename, docCreated, versions) {
return list ? ` return list ? `
<li class="picker-header"> <li class="picker-header">
<a href="#"> <a href="#alt-docs" aria-controls="alt-docs">
<span class="picker-arrow"></span> <span class="picker-arrow"></span>
Other versions Other versions
</a> </a>
<div class="picker"><ol id="alt-docs">${list}</ol></div> <div class="picker" tabindex="-1"><ol id="alt-docs">${list}</ol></div>
</li> </li>
` : ''; ` : '';
} }
@ -557,12 +557,12 @@ function gtocPicker(id) {
return ` return `
<li class="picker-header"> <li class="picker-header">
<a href="#"> <a href="#gtoc-picker" aria-controls="gtoc-picker">
<span class="picker-arrow"></span> <span class="picker-arrow"></span>
Index Index
</a> </a>
<div class="picker">${gtoc}</div> <div class="picker" tabindex="-1" id="gtoc-picker">${gtoc}</div>
</li> </li>
`; `;
} }
@ -574,12 +574,12 @@ function tocPicker(id, content) {
return ` return `
<li class="picker-header"> <li class="picker-header">
<a href="#"> <a href="#toc-picker" aria-controls="toc-picker">
<span class="picker-arrow"></span> <span class="picker-arrow"></span>
Table of contents Table of contents
</a> </a>
<div class="picker">${content.tocPicker}</div> <div class="picker" tabindex="-1">${content.tocPicker.replace('<ul', '<ul id="toc-picker"')}</div>
</li> </li>
`; `;
} }