|
39 | 39 | }
|
40 | 40 |
|
41 | 41 | (function createTabs() {
|
| 42 | + /* the accessibility options of this component have been defined according to: */ |
| 43 | + /* www.w3.org/WAI/ARIA/apg/example-index/tabs/tabs-manual.html */ |
42 | 44 | var tabGroups = document.querySelectorAll('.sf-tabs:not([data-processed=true])');
|
43 | 45 |
|
44 | 46 | /* create the tab navigation for each group of tabs */
|
45 | 47 | for (var i = 0; i < tabGroups.length; i++) {
|
46 | 48 | var tabs = tabGroups[i].querySelectorAll(':scope > .tab');
|
47 |
| - var tabNavigation = document.createElement('ul'); |
| 49 | + var tabNavigation = document.createElement('div'); |
48 | 50 | tabNavigation.className = 'tab-navigation';
|
| 51 | + tabNavigation.setAttribute('role', 'tablist'); |
49 | 52 |
|
50 | 53 | var selectedTabId = 'tab-' + i + '-0'; /* select the first tab by default */
|
51 | 54 | for (var j = 0; j < tabs.length; j++) {
|
52 | 55 | var tabId = 'tab-' + i + '-' + j;
|
53 | 56 | var tabTitle = tabs[j].querySelector('.tab-title').innerHTML;
|
54 | 57 |
|
55 |
| - var tabNavigationItem = document.createElement('li'); |
| 58 | + var tabNavigationItem = document.createElement('button'); |
| 59 | + addClass(tabNavigationItem, 'tab-control'); |
56 | 60 | tabNavigationItem.setAttribute('data-tab-id', tabId);
|
| 61 | + tabNavigationItem.setAttribute('role', 'tab'); |
| 62 | + tabNavigationItem.setAttribute('aria-controls', tabId); |
57 | 63 | if (hasClass(tabs[j], 'active')) { selectedTabId = tabId; }
|
58 |
| - if (hasClass(tabs[j], 'disabled')) { addClass(tabNavigationItem, 'disabled'); } |
| 64 | + if (hasClass(tabs[j], 'disabled')) { |
| 65 | + addClass(tabNavigationItem, 'disabled'); |
| 66 | + } |
59 | 67 | tabNavigationItem.innerHTML = tabTitle;
|
60 | 68 | tabNavigation.appendChild(tabNavigationItem);
|
61 | 69 |
|
|
69 | 77 |
|
70 | 78 | /* display the active tab and add the 'click' event listeners */
|
71 | 79 | for (i = 0; i < tabGroups.length; i++) {
|
72 |
| - tabNavigation = tabGroups[i].querySelectorAll(':scope >.tab-navigation li'); |
| 80 | + tabNavigation = tabGroups[i].querySelectorAll(':scope > .tab-navigation .tab-control'); |
73 | 81 |
|
74 | 82 | for (j = 0; j < tabNavigation.length; j++) {
|
75 | 83 | tabId = tabNavigation[j].getAttribute('data-tab-id');
|
76 |
| - document.getElementById(tabId).querySelector('.tab-title').className = 'hidden'; |
| 84 | + var tabPanel = document.getElementById(tabId); |
| 85 | + tabPanel.setAttribute('role', 'tabpanel'); |
| 86 | + tabPanel.setAttribute('aria-labelledby', tabId); |
| 87 | + tabPanel.querySelector('.tab-title').className = 'hidden'; |
77 | 88 |
|
78 | 89 | if (hasClass(tabNavigation[j], 'active')) {
|
79 |
| - document.getElementById(tabId).className = 'block'; |
| 90 | + tabPanel.className = 'block'; |
| 91 | + tabNavigation[j].setAttribute('aria-selected', 'true'); |
| 92 | + tabNavigation[j].removeAttribute('tabindex'); |
80 | 93 | } else {
|
81 |
| - document.getElementById(tabId).className = 'hidden'; |
| 94 | + tabPanel.className = 'hidden'; |
| 95 | + tabNavigation[j].removeAttribute('aria-selected'); |
| 96 | + tabNavigation[j].setAttribute('tabindex', '-1'); |
82 | 97 | }
|
83 | 98 |
|
84 | 99 | tabNavigation[j].addEventListener('click', function(e) {
|
85 | 100 | var activeTab = e.target || e.srcElement;
|
86 | 101 |
|
87 | 102 | /* needed because when the tab contains HTML contents, user can click */
|
88 |
| - /* on any of those elements instead of their parent '<li>' element */ |
89 |
| - while (activeTab.tagName.toLowerCase() !== 'li') { |
| 103 | + /* on any of those elements instead of their parent '<button>' element */ |
| 104 | + while (activeTab.tagName.toLowerCase() !== 'button') { |
90 | 105 | activeTab = activeTab.parentNode;
|
91 | 106 | }
|
92 | 107 |
|
|
96 | 111 | var tabId = tabNavigation[k].getAttribute('data-tab-id');
|
97 | 112 | document.getElementById(tabId).className = 'hidden';
|
98 | 113 | removeClass(tabNavigation[k], 'active');
|
| 114 | + tabNavigation[k].removeAttribute('aria-selected'); |
| 115 | + tabNavigation[k].setAttribute('tabindex', '-1'); |
99 | 116 | }
|
100 | 117 |
|
101 | 118 | addClass(activeTab, 'active');
|
| 119 | + activeTab.setAttribute('aria-selected', 'true'); |
| 120 | + activeTab.removeAttribute('tabindex'); |
102 | 121 | var activeTabId = activeTab.getAttribute('data-tab-id');
|
103 | 122 | document.getElementById(activeTabId).className = 'block';
|
104 | 123 | });
|
|
0 commit comments