Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit efc9723

Browse files
javiereguiluzfabpot
authored andcommitted
[WebProfilerBundle] Improve accessibility of tabs and some links
1 parent e9870a4 commit efc9723

File tree

3 files changed

+55
-32
lines changed

3 files changed

+55
-32
lines changed

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,28 @@
5555
{% set filters = collector.filters %}
5656
<div class="log-filters">
5757
<div id="log-filter-type" class="log-filter">
58-
<ul class="tab-navigation">
59-
<li class="{{ not has_error_logs and not has_deprecation_logs ? 'active' }}">
58+
<div class="tab-navigation" role="tablist">
59+
<button role="tab" class="tab-control {{ not has_error_logs and not has_deprecation_logs ? 'active' }}">
6060
<input {{ not has_error_logs and not has_deprecation_logs ? 'checked' }} type="radio" id="filter-log-type-all" name="filter-log-type" value="all">
6161
<label for="filter-log-type-all">All messages</label>
62-
</li>
62+
</button>
6363

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

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

8282
<details id="log-filter-priority" class="log-filter">

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -663,23 +663,31 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
663663
},
664664
665665
createTabs: function() {
666+
/* the accessibility options of this component have been defined according to: */
667+
/* www.w3.org/WAI/ARIA/apg/example-index/tabs/tabs-manual.html */
666668
var tabGroups = document.querySelectorAll('.sf-tabs:not([data-processed=true])');
667669
668670
/* create the tab navigation for each group of tabs */
669671
for (var i = 0; i < tabGroups.length; i++) {
670672
var tabs = tabGroups[i].querySelectorAll(':scope > .tab');
671-
var tabNavigation = document.createElement('ul');
673+
var tabNavigation = document.createElement('div');
672674
tabNavigation.className = 'tab-navigation';
675+
tabNavigation.setAttribute('role', 'tablist');
673676
674677
var selectedTabId = 'tab-' + i + '-0'; /* select the first tab by default */
675678
for (var j = 0; j < tabs.length; j++) {
676679
var tabId = 'tab-' + i + '-' + j;
677680
var tabTitle = tabs[j].querySelector('.tab-title').innerHTML;
678681
679-
var tabNavigationItem = document.createElement('li');
682+
var tabNavigationItem = document.createElement('button');
683+
tabNavigationItem.classList.add('tab-control');
680684
tabNavigationItem.setAttribute('data-tab-id', tabId);
685+
tabNavigationItem.setAttribute('role', 'tab');
686+
tabNavigationItem.setAttribute('aria-controls', tabId);
681687
if (hasClass(tabs[j], 'active')) { selectedTabId = tabId; }
682-
if (hasClass(tabs[j], 'disabled')) { addClass(tabNavigationItem, 'disabled'); }
688+
if (hasClass(tabs[j], 'disabled')) {
689+
addClass(tabNavigationItem, 'disabled');
690+
}
683691
tabNavigationItem.innerHTML = tabTitle;
684692
tabNavigation.appendChild(tabNavigationItem);
685693
@@ -693,24 +701,31 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
693701
694702
/* display the active tab and add the 'click' event listeners */
695703
for (i = 0; i < tabGroups.length; i++) {
696-
tabNavigation = tabGroups[i].querySelectorAll(':scope > .tab-navigation li');
704+
tabNavigation = tabGroups[i].querySelectorAll(':scope > .tab-navigation .tab-control');
697705
698706
for (j = 0; j < tabNavigation.length; j++) {
699707
tabId = tabNavigation[j].getAttribute('data-tab-id');
700-
document.getElementById(tabId).querySelector('.tab-title').className = 'hidden';
708+
const tabPanel = document.getElementById(tabId);
709+
tabPanel.setAttribute('role', 'tabpanel');
710+
tabPanel.setAttribute('aria-labelledby', tabId);
711+
tabPanel.querySelector('.tab-title').className = 'hidden';
701712
702713
if (hasClass(tabNavigation[j], 'active')) {
703-
document.getElementById(tabId).className = 'block';
714+
tabPanel.className = 'block';
715+
tabNavigation[j].setAttribute('aria-selected', 'true');
716+
tabNavigation[j].removeAttribute('tabindex');
704717
} else {
705-
document.getElementById(tabId).className = 'hidden';
718+
tabPanel.className = 'hidden';
719+
tabNavigation[j].removeAttribute('aria-selected');
720+
tabNavigation[j].setAttribute('tabindex', '-1');
706721
}
707722
708723
tabNavigation[j].addEventListener('click', function(e) {
709724
var activeTab = e.target || e.srcElement;
710725
711726
/* needed because when the tab contains HTML contents, user can click */
712-
/* on any of those elements instead of their parent '<li>' element */
713-
while (activeTab.tagName.toLowerCase() !== 'li') {
727+
/* on any of those elements instead of their parent '<button>' element */
728+
while (activeTab.tagName.toLowerCase() !== 'button') {
714729
activeTab = activeTab.parentNode;
715730
}
716731
@@ -720,9 +735,13 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
720735
var tabId = tabNavigation[k].getAttribute('data-tab-id');
721736
document.getElementById(tabId).className = 'hidden';
722737
removeClass(tabNavigation[k], 'active');
738+
tabNavigation[k].removeAttribute('aria-selected');
739+
tabNavigation[k].setAttribute('tabindex', '-1');
723740
}
724741
725742
addClass(activeTab, 'active');
743+
activeTab.setAttribute('aria-selected', 'true');
744+
activeTab.removeAttribute('tabindex');
726745
var activeTabId = activeTab.getAttribute('data-tab-id');
727746
document.getElementById(activeTabId).className = 'block';
728747
});
@@ -894,7 +913,7 @@ if (typeof Sfjs === 'undefined' || typeof Sfjs.loadToolbar === 'undefined') {
894913
document.querySelector('#log-filter-channel .filter-active-num').innerText = (channels.length === selectedChannels.length) ? 'All' : selectedChannels.length;
895914
896915
/* update the currently selected "log type" tab */
897-
document.querySelectorAll('#log-filter-type li').forEach((tab) => tab.classList.remove('active'));
916+
document.querySelectorAll('#log-filter-type .tab-control').forEach((tab) => tab.classList.remove('active'));
898917
document.querySelector(`#log-filter-type input[value="${selectedType}"]`).parentElement.classList.add('active');
899918
},
900919
};

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,6 @@ input[type="radio"], input[type="checkbox"] {
516516
color: var(--color-link);
517517
text-decoration: none;
518518
background-color: transparent;
519-
outline: none;
520519
border: 0;
521520
padding: 0;
522521
cursor: pointer;
@@ -1546,23 +1545,26 @@ tr.status-warning td {
15461545
box-shadow: inset 0 0 0 1px var(--tab-border-color), 0 0 0 4px var(--page-background);
15471546
margin: 0 0 10px;
15481547
}
1549-
.tab-navigation li {
1548+
.tab-navigation .tab-control {
1549+
background: transparent;
1550+
border: 0;
15501551
box-shadow: none;
15511552
transition: box-shadow .05s ease-in, background-color .05s ease-in;
15521553
cursor: pointer;
1554+
font-size: 14px;
15531555
font-weight: 500;
1554-
list-style: none;
1556+
line-height: 1.4;
15551557
margin: 0;
15561558
padding: 4px 14px;
15571559
position: relative;
15581560
text-align: center;
15591561
z-index: 1;
15601562
}
1561-
.sf-tabs-sm .tab-navigation li {
1563+
.sf-tabs-sm .tab-navigation .tab-control {
15621564
font-size: 13px;
15631565
padding: 2.5px 10px;
15641566
}
1565-
.tab-navigation li:before {
1567+
.tab-navigation .tab-control:before {
15661568
background: var(--tab-border-color);
15671569
bottom: 15%;
15681570
content: "";
@@ -1571,10 +1573,12 @@ tr.status-warning td {
15711573
top: 15%;
15721574
width: 1px;
15731575
}
1574-
.tab-navigation li:first-child:before, .tab-navigation li.active + li:before, .tab-navigation li.active:before {
1576+
.tab-navigation .tab-control:first-child:before,
1577+
.tab-navigation .tab-control.active + .tab-control:before,
1578+
.tab-navigation .tab-control.active:before {
15751579
width: 0;
15761580
}
1577-
.tab-navigation li .badge {
1581+
.tab-navigation .tab-control .badge {
15781582
background: var(--selected-badge-background);
15791583
box-shadow: var(--selected-badge-shadow);
15801584
color: var(--selected-badge-color);
@@ -1588,29 +1592,29 @@ tr.status-warning td {
15881592
text-align: center;
15891593
white-space: nowrap;
15901594
}
1591-
.tab-navigation li.disabled {
1595+
.tab-navigation .tab-control.disabled {
15921596
color: var(--tab-disabled-color);
15931597
}
1594-
.tab-navigation li.active {
1598+
.tab-navigation .tab-control.active {
15951599
background-color: var(--tab-active-background);
15961600
border-radius: 6px;
15971601
box-shadow: inset 0 0 0 1.5px var(--tab-active-border-color);
15981602
color: var(--tab-active-color);
15991603
position: relative;
16001604
z-index: 1;
16011605
}
1602-
.theme-dark .tab-navigation li.active {
1606+
.theme-dark .tab-navigation .tab-control.active {
16031607
box-shadow: inset 0 0 0 1px var(--tab-border-color);
16041608
}
16051609
.tab-content > *:first-child {
16061610
margin-top: 0;
16071611
}
1608-
.tab-navigation li .badge.status-warning {
1612+
.tab-navigation .tab-control .badge.status-warning {
16091613
background: var(--selected-badge-warning-background);
16101614
box-shadow: var(--selected-badge-warning-shadow);
16111615
color: var(--selected-badge-warning-color);
16121616
}
1613-
.tab-navigation li .badge.status-error {
1617+
.tab-navigation .tab-control .badge.status-error {
16141618
background: var(--selected-badge-danger-background);
16151619
box-shadow: var(--selected-badge-danger-shadow);
16161620
color: var(--selected-badge-danger-color);
@@ -1784,10 +1788,10 @@ tr.status-warning td {
17841788
font-weight: bold;
17851789
padding: 0 1px;
17861790
}
1787-
.log-filter .tab-navigation li input {
1791+
.log-filter .tab-navigation .tab-control input {
17881792
display: none;
17891793
}
1790-
.log-filter .tab-navigation li label {
1794+
.log-filter .tab-navigation .tab-control label {
17911795
cursor: pointer;
17921796
}
17931797
.log-filters .log-filter .log-filter-content {

0 commit comments

Comments
 (0)