Skip to content

Commit

Permalink
feature #48762 [WebProfilerBundle] Improve accessibility of tabs and …
Browse files Browse the repository at this point in the history
…some links (javiereguiluz)

This PR was squashed before being merged into the 6.3 branch.

Discussion
----------

[WebProfilerBundle] Improve accessibility of tabs and some links

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

This improves Profiler accessibility a bit by:

* Showing an outline in "link buttons" when navigating with the keyboard
* Adding full ARIA attributes to our tabs, which are common in many panels

Commits
-------

efc9723 [WebProfilerBundle] Improve accessibility of tabs and some links
  • Loading branch information
fabpot committed Jan 11, 2023
2 parents f65e098 + efc9723 commit a8ad6bb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,28 +55,28 @@
{% set filters = collector.filters %}
<div class="log-filters">
<div id="log-filter-type" class="log-filter">
<ul class="tab-navigation">
<li class="{{ not has_error_logs and not has_deprecation_logs ? 'active' }}">
<div class="tab-navigation" role="tablist">
<button role="tab" class="tab-control {{ not has_error_logs and not has_deprecation_logs ? 'active' }}">
<input {{ not has_error_logs and not has_deprecation_logs ? 'checked' }} type="radio" id="filter-log-type-all" name="filter-log-type" value="all">
<label for="filter-log-type-all">All messages</label>
</li>
</button>

<li class="{{ has_error_logs ? 'active' }}">
<button role="tab" class="tab-control {{ has_error_logs ? 'active' }}">
<input {{ has_error_logs ? 'checked' }} type="radio" id="filter-log-type-error" name="filter-log-type" value="error">
<label for="filter-log-type-error">
Errors
<span class="badge status-{{ collector.counterrors ? 'error' }}">{{ collector.counterrors|default(0) }}</span>
</label>
</li>
</button>

<li class="{{ not has_error_logs and has_deprecation_logs ? 'active' }}">
<button role="tab" class="tab-control {{ not has_error_logs and has_deprecation_logs ? 'active' }}">
<input {{ not has_error_logs and has_deprecation_logs ? 'checked' }} type="radio" id="filter-log-type-deprecation" name="filter-log-type" value="deprecation">
<label for="filter-log-type-deprecation">
Deprecations
<span class="badge status-{{ collector.countdeprecations ? 'warning' }}">{{ collector.countdeprecations|default(0) }}</span>
</label>
</li>
</ul>
</button>
</div>
</div>

<details id="log-filter-priority" class="log-filter">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,23 +663,31 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
},
createTabs: function() {
/* the accessibility options of this component have been defined according to: */
/* www.w3.org/WAI/ARIA/apg/example-index/tabs/tabs-manual.html */
var tabGroups = document.querySelectorAll('.sf-tabs:not([data-processed=true])');
/* create the tab navigation for each group of tabs */
for (var i = 0; i < tabGroups.length; i++) {
var tabs = tabGroups[i].querySelectorAll(':scope > .tab');
var tabNavigation = document.createElement('ul');
var tabNavigation = document.createElement('div');
tabNavigation.className = 'tab-navigation';
tabNavigation.setAttribute('role', 'tablist');
var selectedTabId = 'tab-' + i + '-0'; /* select the first tab by default */
for (var j = 0; j < tabs.length; j++) {
var tabId = 'tab-' + i + '-' + j;
var tabTitle = tabs[j].querySelector('.tab-title').innerHTML;
var tabNavigationItem = document.createElement('li');
var tabNavigationItem = document.createElement('button');
tabNavigationItem.classList.add('tab-control');
tabNavigationItem.setAttribute('data-tab-id', tabId);
tabNavigationItem.setAttribute('role', 'tab');
tabNavigationItem.setAttribute('aria-controls', tabId);
if (hasClass(tabs[j], 'active')) { selectedTabId = tabId; }
if (hasClass(tabs[j], 'disabled')) { addClass(tabNavigationItem, 'disabled'); }
if (hasClass(tabs[j], 'disabled')) {
addClass(tabNavigationItem, 'disabled');
}
tabNavigationItem.innerHTML = tabTitle;
tabNavigation.appendChild(tabNavigationItem);
Expand All @@ -693,24 +701,31 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
/* display the active tab and add the 'click' event listeners */
for (i = 0; i < tabGroups.length; i++) {
tabNavigation = tabGroups[i].querySelectorAll(':scope > .tab-navigation li');
tabNavigation = tabGroups[i].querySelectorAll(':scope > .tab-navigation .tab-control');
for (j = 0; j < tabNavigation.length; j++) {
tabId = tabNavigation[j].getAttribute('data-tab-id');
document.getElementById(tabId).querySelector('.tab-title').className = 'hidden';
const tabPanel = document.getElementById(tabId);
tabPanel.setAttribute('role', 'tabpanel');
tabPanel.setAttribute('aria-labelledby', tabId);
tabPanel.querySelector('.tab-title').className = 'hidden';
if (hasClass(tabNavigation[j], 'active')) {
document.getElementById(tabId).className = 'block';
tabPanel.className = 'block';
tabNavigation[j].setAttribute('aria-selected', 'true');
tabNavigation[j].removeAttribute('tabindex');
} else {
document.getElementById(tabId).className = 'hidden';
tabPanel.className = 'hidden';
tabNavigation[j].removeAttribute('aria-selected');
tabNavigation[j].setAttribute('tabindex', '-1');
}
tabNavigation[j].addEventListener('click', function(e) {
var activeTab = e.target || e.srcElement;
/* needed because when the tab contains HTML contents, user can click */
/* on any of those elements instead of their parent '<li>' element */
while (activeTab.tagName.toLowerCase() !== 'li') {
/* on any of those elements instead of their parent '<button>' element */
while (activeTab.tagName.toLowerCase() !== 'button') {
activeTab = activeTab.parentNode;
}
Expand All @@ -720,9 +735,13 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
var tabId = tabNavigation[k].getAttribute('data-tab-id');
document.getElementById(tabId).className = 'hidden';
removeClass(tabNavigation[k], 'active');
tabNavigation[k].removeAttribute('aria-selected');
tabNavigation[k].setAttribute('tabindex', '-1');
}
addClass(activeTab, 'active');
activeTab.setAttribute('aria-selected', 'true');
activeTab.removeAttribute('tabindex');
var activeTabId = activeTab.getAttribute('data-tab-id');
document.getElementById(activeTabId).className = 'block';
});
Expand Down Expand Up @@ -892,7 +911,7 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
document.querySelector('#log-filter-channel .filter-active-num').innerText = (channels.length === selectedChannels.length) ? 'All' : selectedChannels.length;
/* update the currently selected "log type" tab */
document.querySelectorAll('#log-filter-type li').forEach((tab) => tab.classList.remove('active'));
document.querySelectorAll('#log-filter-type .tab-control').forEach((tab) => tab.classList.remove('active'));
document.querySelector(`#log-filter-type input[value="${selectedType}"]`).parentElement.classList.add('active');
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ input[type="radio"], input[type="checkbox"] {
color: var(--color-link);
text-decoration: none;
background-color: transparent;
outline: none;
border: 0;
padding: 0;
cursor: pointer;
Expand Down Expand Up @@ -1551,23 +1550,26 @@ tr.status-warning td {
box-shadow: inset 0 0 0 1px var(--tab-border-color), 0 0 0 4px var(--page-background);
margin: 0 0 10px;
}
.tab-navigation li {
.tab-navigation .tab-control {
background: transparent;
border: 0;
box-shadow: none;
transition: box-shadow .05s ease-in, background-color .05s ease-in;
cursor: pointer;
font-size: 14px;
font-weight: 500;
list-style: none;
line-height: 1.4;
margin: 0;
padding: 4px 14px;
position: relative;
text-align: center;
z-index: 1;
}
.sf-tabs-sm .tab-navigation li {
.sf-tabs-sm .tab-navigation .tab-control {
font-size: 13px;
padding: 2.5px 10px;
}
.tab-navigation li:before {
.tab-navigation .tab-control:before {
background: var(--tab-border-color);
bottom: 15%;
content: "";
Expand All @@ -1576,10 +1578,12 @@ tr.status-warning td {
top: 15%;
width: 1px;
}
.tab-navigation li:first-child:before, .tab-navigation li.active + li:before, .tab-navigation li.active:before {
.tab-navigation .tab-control:first-child:before,
.tab-navigation .tab-control.active + .tab-control:before,
.tab-navigation .tab-control.active:before {
width: 0;
}
.tab-navigation li .badge {
.tab-navigation .tab-control .badge {
background: var(--selected-badge-background);
box-shadow: var(--selected-badge-shadow);
color: var(--selected-badge-color);
Expand All @@ -1593,29 +1597,29 @@ tr.status-warning td {
text-align: center;
white-space: nowrap;
}
.tab-navigation li.disabled {
.tab-navigation .tab-control.disabled {
color: var(--tab-disabled-color);
}
.tab-navigation li.active {
.tab-navigation .tab-control.active {
background-color: var(--tab-active-background);
border-radius: 6px;
box-shadow: inset 0 0 0 1.5px var(--tab-active-border-color);
color: var(--tab-active-color);
position: relative;
z-index: 1;
}
.theme-dark .tab-navigation li.active {
.theme-dark .tab-navigation .tab-control.active {
box-shadow: inset 0 0 0 1px var(--tab-border-color);
}
.tab-content > *:first-child {
margin-top: 0;
}
.tab-navigation li .badge.status-warning {
.tab-navigation .tab-control .badge.status-warning {
background: var(--selected-badge-warning-background);
box-shadow: var(--selected-badge-warning-shadow);
color: var(--selected-badge-warning-color);
}
.tab-navigation li .badge.status-error {
.tab-navigation .tab-control .badge.status-error {
background: var(--selected-badge-danger-background);
box-shadow: var(--selected-badge-danger-shadow);
color: var(--selected-badge-danger-color);
Expand Down Expand Up @@ -1789,10 +1793,10 @@ tr.status-warning td {
font-weight: bold;
padding: 0 1px;
}
.log-filter .tab-navigation li input {
.log-filter .tab-navigation .tab-control input {
display: none;
}
.log-filter .tab-navigation li label {
.log-filter .tab-navigation .tab-control label {
cursor: pointer;
}
.log-filters .log-filter .log-filter-content {
Expand Down

0 comments on commit a8ad6bb

Please sign in to comment.