Skip to content

Commit 5b8eb5b

Browse files
Merge pull request #94 from gooddata/fix/tab-order
fix: add tabindex handling for sidebar mobile trigger accessibility
2 parents 8cc12f4 + fcf222e commit 5b8eb5b

3 files changed

Lines changed: 62 additions & 2 deletions

File tree

layouts/partials/hooks/body-end.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
<script src="/js/embedded-image.js"></script>
1010
<script src="/js/heading-anchor.js"></script>
1111
<script src="/js/prism-accessibility.js"></script>
12+
<script src="/js/tab-order.js"></script>

layouts/partials/sidebar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{{/* (C) 2023 GoodData Corporation */}}
2-
<button tabindex="6" type="button" id="gd-docs-menu__mobile-trigger" class="gd-docs-menu__mobile-btn" aria-expanded="false" aria-controls="gd-docs-menu" aria-label="Toggle navigation menu">
2+
<button type="button" id="gd-docs-menu__mobile-trigger" class="gd-docs-menu__mobile-btn" aria-expanded="false" aria-controls="gd-docs-menu" aria-label="Toggle navigation menu">
33
<span class="gd-docs-menu__mobile-icon" aria-hidden="true"></span>
44
</button>
55
<div class="gd-docs-menu__mobile-bg"></div>
66
<nav id="gd-docs-menu" class="gd-docs-menu init" aria-label="Articles">
77
<div class="sidebar-skip-links">
88
<a href="#main-content" class="skip-link skip-link--sidebar">Skip to main content</a>
99
</div>
10-
10+
1111
{{ if .Site.Params.versions }}
1212
{{ partial "navbar-version-selector.html" . }}
1313
{{ end }}

static/js/tab-order.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
$(document).ready(function () {
2+
// mobile menu trigger
3+
const mobileTrigger = $("#gd-header-mobile-menu-trigger-input");
4+
// sidebar trigger
5+
const sideTrigger = $("#gd-docs-menu__mobile-trigger");
6+
7+
// Initial check
8+
if (mobileTrigger.attr('aria-expanded') === 'false') {
9+
sideTrigger.attr('tabindex', 6)
10+
}
11+
12+
// Function to handle aria-expanded changes
13+
function handleAriaExpandedChange(element, isExpanded) {
14+
const elementId = element.attr('id');
15+
16+
if (elementId === 'gd-header-mobile-menu-trigger-input') {
17+
// Mobile menu trigger logic
18+
if (isExpanded) {
19+
sideTrigger.removeAttr('tabindex');
20+
} else {
21+
sideTrigger.attr('tabindex', 6);
22+
}
23+
} else if (elementId === 'gd-docs-menu__mobile-trigger') {
24+
// Sidebar trigger logic
25+
if (isExpanded) {
26+
sideTrigger.removeAttr('tabindex');
27+
} else {
28+
sideTrigger.attr('tabindex', 6);
29+
}
30+
}
31+
}
32+
33+
// Create observer for both elements
34+
const observer = new MutationObserver(function(mutations) {
35+
mutations.forEach(function(mutation) {
36+
if (mutation.attributeName === 'aria-expanded') {
37+
const $target = $(mutation.target);
38+
const isExpanded = $target.attr('aria-expanded') === 'true';
39+
handleAriaExpandedChange($target, isExpanded);
40+
}
41+
});
42+
});
43+
44+
// Observe mobile trigger
45+
if (mobileTrigger.length > 0) {
46+
observer.observe(mobileTrigger[0], {
47+
attributes: true,
48+
attributeFilter: ['aria-expanded']
49+
});
50+
}
51+
52+
// Observe sidebar trigger
53+
if (sideTrigger.length > 0) {
54+
observer.observe(sideTrigger[0], {
55+
attributes: true,
56+
attributeFilter: ['aria-expanded']
57+
});
58+
}
59+
});

0 commit comments

Comments
 (0)