Skip to content

Fix: Accessibility roles and aria labels #2304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Nov 29, 2023
2 changes: 2 additions & 0 deletions src/core/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ export function Render(Base) {
let navAppendToTarget = dom.body;

if (el) {
navEl.setAttribute('aria-label', 'secondary');

if (config.repo) {
html += tpl.corner(config.repo, config.cornerExternalLinkTarget);
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/render/progressbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ function init() {
const div = dom.create('div');

div.classList.add('progress');
div.setAttribute('role', 'progressbar');
div.setAttribute('aria-valuemin', '0');
div.setAttribute('aria-valuemax', '100');
div.setAttribute('aria-label', 'Loading...');
dom.appendTo(dom.body, div);
barEl = div;
}
Expand All @@ -33,13 +37,15 @@ export default function (info) {

barEl.style.opacity = 1;
barEl.style.width = num >= 95 ? '100%' : num + '%';
barEl.setAttribute('aria-valuenow', num >= 95 ? 100 : num);

if (num >= 95) {
clearTimeout(timeId);
// eslint-disable-next-line no-unused-vars
timeId = setTimeout(_ => {
barEl.style.opacity = 0;
barEl.style.width = '0%';
barEl.removeAttribute('aria-valuenow');
}, 200);
}
}
10 changes: 5 additions & 5 deletions src/core/render/tpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function main(config) {
<span></span><span></span><span></span>
</div>
</button>
<aside class="sidebar">
<aside class="sidebar" role="none">
${
config.name
? /* html */ `
Expand All @@ -52,14 +52,14 @@ export function main(config) {
`
: ''
}
<div class="sidebar-nav"><!--sidebar--></div>
<div class="sidebar-nav" role="navigation" aria-label="primary"><!--sidebar--></div>
</aside>
`;

return /* html */ `
<main>${aside}
<main role="presentation">${aside}
<section class="content">
<article class="markdown-section" id="main"><!--main--></article>
<article class="markdown-section" id="main" role="main"><!--main--></article>
</section>
</main>
`;
Expand All @@ -80,7 +80,7 @@ export function cover() {
`;

return /* html */ `
<section class="cover show" style="background: ${bgc}">
<section class="cover show" role="complementary" aria-label="cover" style="background: ${bgc}">
<div class="mask"></div>
<div class="cover-main"><!--cover--></div>
</section>
Expand Down
17 changes: 14 additions & 3 deletions src/plugins/search/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ function style() {
align-items: center;
}

.search .results-status:not(:empty) {
margin-top: 10px;
font-size: smaller;
}

.search .results-panel {
display: none;
}
Expand Down Expand Up @@ -122,12 +127,14 @@ function tpl(defaultValue = '') {
</svg>
</div>
</div>
<div class="results-status" aria-live="polite"></div>
<div class="results-panel"></div>
`;
const el = Docsify.dom.create('div', html);
const aside = Docsify.dom.find('aside');

Docsify.dom.toggleClass(el, 'search');
el.setAttribute('role', 'search');
Docsify.dom.before(aside, el);
}

Expand All @@ -136,12 +143,14 @@ function doSearch(value) {
const $panel = Docsify.dom.find($search, '.results-panel');
const $clearBtn = Docsify.dom.find($search, '.clear-button');
const $sidebarNav = Docsify.dom.find('.sidebar-nav');
const $status = Docsify.dom.find('div.search .results-status');
const $appName = Docsify.dom.find('.app-name');

if (!value) {
$panel.classList.remove('show');
$clearBtn.classList.remove('show');
$panel.innerHTML = '';
$status.textContent = '';

if (options.hideOtherSidebarContent) {
$sidebarNav && $sidebarNav.classList.remove('hide');
Expand All @@ -151,12 +160,12 @@ function doSearch(value) {
return;
}

const matchs = search(value);
const matches = search(value);

let html = '';
matchs.forEach(post => {
matches.forEach((post, i) => {
html += /* html */ `
<div class="matching-post">
<div class="matching-post" aria-label="search result ${i + 1}">
<a href="${post.url}">
<h2>${post.title}</h2>
<p>${post.content}</p>
Expand All @@ -168,6 +177,8 @@ function doSearch(value) {
$panel.classList.add('show');
$clearBtn.classList.add('show');
$panel.innerHTML = html || /* html */ `<p class="empty">${NO_DATA_TEXT}</p>`;
$status.textContent = `Found ${matches.length} results`;

if (options.hideOtherSidebarContent) {
$sidebarNav && $sidebarNav.classList.add('hide');
$appName && $appName.classList.add('hide');
Expand Down
8 changes: 4 additions & 4 deletions test/integration/__snapshots__/docs.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Docs Site coverpage renders and is unchanged 1`] = `
"<section class=\\"cover show\\" style=\\"background:
"<section class=\\"cover show\\" role=\\"complementary\\" aria-label=\\"cover\\" style=\\"background:
linear-gradient(
to left bottom,
hsl(127, 100%, 85%) 0%,
Expand All @@ -16,11 +16,11 @@ exports[`Docs Site coverpage renders and is unchanged 1`] = `
</section>"
`;

exports[`Docs Site navbar renders and is unchanged 1`] = `"<nav class=\\"app-nav no-badge\\"><ul><li>Translations<ul><li><a href=\\"#/\\" title=\\"undefined\\" class=\\"active\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ec-1f1e7.png?v8.png\\" alt=\\"uk\\" class=\\"emoji\\" loading=\\"lazy\\"> English</a></li><li><a href=\\"#/zh-cn/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e8-1f1f3.png?v8.png\\" alt=\\"cn\\" class=\\"emoji\\" loading=\\"lazy\\"> 简体中文</a></li><li><a href=\\"#/de-de/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e9-1f1ea.png?v8.png\\" alt=\\"de\\" class=\\"emoji\\" loading=\\"lazy\\"> Deutsch</a></li><li><a href=\\"#/es/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ea-1f1f8.png?v8.png\\" alt=\\"es\\" class=\\"emoji\\" loading=\\"lazy\\"> Español</a></li><li><a href=\\"#/ru-ru/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1f7-1f1fa.png?v8.png\\" alt=\\"ru\\" class=\\"emoji\\" loading=\\"lazy\\"> Русский</a></li></ul></li></ul></nav>"`;
exports[`Docs Site navbar renders and is unchanged 1`] = `"<nav aria-label=\\"secondary\\" class=\\"app-nav no-badge\\"><ul><li>Translations<ul><li><a href=\\"#/\\" title=\\"undefined\\" class=\\"active\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ec-1f1e7.png?v8.png\\" alt=\\"uk\\" class=\\"emoji\\" loading=\\"lazy\\"> English</a></li><li><a href=\\"#/zh-cn/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e8-1f1f3.png?v8.png\\" alt=\\"cn\\" class=\\"emoji\\" loading=\\"lazy\\"> 简体中文</a></li><li><a href=\\"#/de-de/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e9-1f1ea.png?v8.png\\" alt=\\"de\\" class=\\"emoji\\" loading=\\"lazy\\"> Deutsch</a></li><li><a href=\\"#/es/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ea-1f1f8.png?v8.png\\" alt=\\"es\\" class=\\"emoji\\" loading=\\"lazy\\"> Español</a></li><li><a href=\\"#/ru-ru/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1f7-1f1fa.png?v8.png\\" alt=\\"ru\\" class=\\"emoji\\" loading=\\"lazy\\"> Русский</a></li></ul></li></ul></nav>"`;

exports[`Docs Site sidebar renders and is unchanged 1`] = `
"<aside class=\\"sidebar\\">
"<aside class=\\"sidebar\\" role=\\"none\\">

<div class=\\"sidebar-nav\\"><ul><li><p>Getting started</p><ul><li><a href=\\"#/quickstart\\" title=\\"undefined\\">Quick start</a></li><li><a href=\\"#/more-pages\\" title=\\"undefined\\">Writing more pages</a></li><li><a href=\\"#/custom-navbar\\" title=\\"undefined\\">Custom navbar</a></li><li><a href=\\"#/cover\\" title=\\"undefined\\">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href=\\"#/configuration\\" title=\\"undefined\\">Configuration</a></li><li><a href=\\"#/themes\\" title=\\"undefined\\">Themes</a></li><li><a href=\\"#/plugins\\" title=\\"undefined\\">List of Plugins</a></li><li><a href=\\"#/write-a-plugin\\" title=\\"undefined\\">Write a Plugin</a></li><li><a href=\\"#/markdown\\" title=\\"undefined\\">Markdown configuration</a></li><li><a href=\\"#/language-highlight\\" title=\\"undefined\\">Language highlighting</a></li><li><a href=\\"#/emoji\\" title=\\"undefined\\">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href=\\"#/deploy\\" title=\\"undefined\\">Deploy</a></li><li><a href=\\"#/helpers\\" title=\\"undefined\\">Helpers</a></li><li><a href=\\"#/vue\\" title=\\"undefined\\">Vue compatibility</a></li><li><a href=\\"#/cdn\\" title=\\"undefined\\">CDN</a></li><li><a href=\\"#/pwa\\" title=\\"undefined\\">Offline Mode (PWA)</a></li><li><a href=\\"#/embed-files\\" title=\\"undefined\\">Embed Files</a></li></ul></li><li><p><a href=\\"#/awesome\\" title=\\"undefined\\">Awesome docsify</a></p></li><li><p><a href=\\"#/changelog\\" title=\\"undefined\\">Changelog</a></p></li></ul></div>
<div class=\\"sidebar-nav\\" role=\\"navigation\\" aria-label=\\"primary\\"><ul><li><p>Getting started</p><ul><li><a href=\\"#/quickstart\\" title=\\"undefined\\">Quick start</a></li><li><a href=\\"#/more-pages\\" title=\\"undefined\\">Writing more pages</a></li><li><a href=\\"#/custom-navbar\\" title=\\"undefined\\">Custom navbar</a></li><li><a href=\\"#/cover\\" title=\\"undefined\\">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href=\\"#/configuration\\" title=\\"undefined\\">Configuration</a></li><li><a href=\\"#/themes\\" title=\\"undefined\\">Themes</a></li><li><a href=\\"#/plugins\\" title=\\"undefined\\">List of Plugins</a></li><li><a href=\\"#/write-a-plugin\\" title=\\"undefined\\">Write a Plugin</a></li><li><a href=\\"#/markdown\\" title=\\"undefined\\">Markdown configuration</a></li><li><a href=\\"#/language-highlight\\" title=\\"undefined\\">Language highlighting</a></li><li><a href=\\"#/emoji\\" title=\\"undefined\\">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href=\\"#/deploy\\" title=\\"undefined\\">Deploy</a></li><li><a href=\\"#/helpers\\" title=\\"undefined\\">Helpers</a></li><li><a href=\\"#/vue\\" title=\\"undefined\\">Vue compatibility</a></li><li><a href=\\"#/cdn\\" title=\\"undefined\\">CDN</a></li><li><a href=\\"#/pwa\\" title=\\"undefined\\">Offline Mode (PWA)</a></li><li><a href=\\"#/embed-files\\" title=\\"undefined\\">Embed Files</a></li></ul></li><li><p><a href=\\"#/awesome\\" title=\\"undefined\\">Awesome docsify</a></p></li><li><p><a href=\\"#/changelog\\" title=\\"undefined\\">Changelog</a></p></li></ul></div>
</aside>"
`;