* Api: Sidebox accessibility improvements

- Using nav elements for sidebox categories
- Add keyboard support for expand/collapse menu categories
- Use lists for entries
- Added some roles for screenreaders
This commit is contained in:
nathangray 2021-05-12 11:34:34 -06:00
parent 992b71a912
commit 45e477f0c0
10 changed files with 715 additions and 704 deletions

View File

@ -303,7 +303,7 @@ var fw_base = (function(){ "use strict"; return Class.extend(
if (_data[i].entries[j].icon_or_star)
{
var disableIfNoEPL = _data[i].entries[j].disableIfNoEPL ? ' disableIfNoEPL" title="'+egw.lang("This feature is only available in EPL version.") : "";
catContent += '<div class="egw_fw_ui_sidemenu_listitem'+disableIfNoEPL+
catContent += '<li class="egw_fw_ui_sidemenu_listitem'+disableIfNoEPL+
'"><img class="egw_fw_ui_sidemenu_listitem_icon" src="' + _data[i].entries[j].icon_or_star + '" />';
}
if (_data[i].entries[j].item_link == '')

View File

@ -79,13 +79,15 @@ var fw_ui_sidemenu_entry = (function(){ "use strict"; return Class.extend(
//close button on active header
this.closeButton = document.createElement('span');
this.closeButton.classList.add('close')
this.closeButton.classList.add('close');
//Create the content div
this.contentDiv = document.createElement("div");
this.contentDiv.id = _app+'_sidebox_content';
jQuery(this.contentDiv).addClass("egw_fw_ui_sidemenu_entry_content");
jQuery(this.contentDiv).addClass("egw_fw_ui_sidemenu_entry_content")
.attr("role","menu")
.attr("aria-label",this.entryName);
jQuery(this.contentDiv).hide();
//Add in invisible marker to store the original position of this element in the DOM tree
@ -408,12 +410,13 @@ function egw_fw_ui_tab(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
}
return true;
}.bind(this.closeButton))
}.bind(this.closeButton));
}
this.contentDiv = document.createElement("div");
jQuery(this.contentDiv).addClass("egw_fw_ui_tab_content");
jQuery(this.contentDiv).hide();
jQuery(this.contentDiv).addClass("egw_fw_ui_tab_content")
.attr("role","application")
.hide();
//Sort the element in at the given position
var _this = this;
@ -846,17 +849,26 @@ function egw_fw_ui_category(_contDiv, _name, _title, _content, _callback, _anima
this.animationCallback = _animationCallback;
this.tag = _tag;
// Unique ID for accessibility
let uid = "sidebox_nav_"+egw.uid();
//Create the ui divs
this.headerDiv = document.createElement('div');
jQuery(this.headerDiv).addClass('egw_fw_ui_category');
this.headerDiv = document.createElement('nav');
jQuery(this.headerDiv).addClass('egw_fw_ui_category')
.attr("aria-haspopup",true)
.attr("aria-labelledby",uid)
.attr("role","section")
.attr("tabindex",0);
//Add the text
var entryH1 = document.createElement('h1');
jQuery(entryH1).append(_title);
jQuery(this.headerDiv).append(entryH1);
var entryH2 = document.createElement('h2');
jQuery(entryH2)
.attr("id",uid)
.append(_title);
jQuery(this.headerDiv).append(entryH2);
//Add the content
this.contentDiv = document.createElement('div');
this.contentDiv = document.createElement('ul');
this.contentDiv._parent = this;
jQuery(this.contentDiv).addClass('egw_fw_ui_category_content');
jQuery(this.contentDiv).append(_content);
@ -864,8 +876,9 @@ function egw_fw_ui_category(_contDiv, _name, _title, _content, _callback, _anima
//Add content and header to the content div, add some magic jQuery code in order to make it foldable
this.headerDiv._parent = this;
jQuery(this.headerDiv).click(
function() {
jQuery(this.headerDiv).on("click keydown",
function(e) {
if([EGW_KEY_ENTER, EGW_KEY_SPACE].indexOf(e.which) == -1) return;
if (!jQuery(this).hasClass('egw_fw_ui_category_active'))
{
this._parent.open(false);
@ -874,15 +887,17 @@ function egw_fw_ui_category(_contDiv, _name, _title, _content, _callback, _anima
{
this._parent.close(false);
}
e.stopPropagation();
});
jQuery(this.contDiv).append(this.headerDiv);
jQuery(this.contDiv).append(this.contentDiv);
jQuery(this.headerDiv).append(this.contentDiv);
}
egw_fw_ui_category.prototype.open = function(_instantly)
{
this.callback.call(this, true);
jQuery(this.headerDiv).addClass('egw_fw_ui_category_active');
jQuery(this.headerDiv).addClass('egw_fw_ui_category_active')
.attr("aria-expanded",true);
if (_instantly)
{
@ -895,12 +910,14 @@ egw_fw_ui_category.prototype.open = function(_instantly)
this._parent.animationCallback.call(this._parent);
});
}
jQuery("li:first-child", this.headerDiv).eq(0).focus();
};
egw_fw_ui_category.prototype.close = function(_instantly)
{
this.callback.call(this, false);
jQuery(this.headerDiv).removeClass('egw_fw_ui_category_active');
jQuery(this.headerDiv).removeClass('egw_fw_ui_category_active')
.attr("aria-expanded", false);
if (_instantly)
{

View File

@ -83,7 +83,7 @@ class Favorites
continue;
}
$li = "<li data-id='$name' data-group='{$filter['group']}' class='ui-menu-item' role='menuitem'>\n";
$li .= '<a href="#" class="ui-corner-all" tabindex="-1">';
$li .= '<a href="#" class="ui-corner-all">';
$li .= "<div class='" . ((string)$name === (string)$default_filter ? 'ui-icon ui-icon-heart' : 'sideboxstar') . "'></div>".
$filter['name'];
$li .= ($filter['group'] != false && !$is_admin || $name === 'blank' ? "" :

View File

@ -3264,7 +3264,7 @@ tr.disableIfNoEPL {
.egw_fw_ui_sidemenu_entry_content hr {
/* HR in sidebox */
border-top: 1px solid silver;
margin: 3px 5px 2px 5px;
margin: 10px 5px 2px 5px;
}
.inactive_blur > * {opacity: 0.4; filter:blur(2px); pointer-events: none;}

File diff suppressed because it is too large Load Diff

View File

@ -474,7 +474,7 @@
&:active {.box_shadow_standard_light_inset;}
h1 {
h1,h2 {
margin: 6px 0 10px 0;
padding-top: 0.31em;
padding-left: 3em;
@ -514,7 +514,7 @@
img {padding-left: 9px; padding-top: 6px; height: 18px;}
h1 {
h1,h2 {
text-transform: uppercase;
font-size: 12px;
.color_100_gray;
@ -555,7 +555,7 @@
.egw_fw_ui_sidemenu_entry_content {
div.egw_fw_ui_category_content {
ul.egw_fw_ui_category_content {
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -191,7 +191,7 @@
.background_color_0_gray;
border-color: @gray_30;
border-right: 0px;
margin-bottom: 10px;
margin-bottom: 0px;
border-top-color: white;
padding-top: 0px;
}
@ -218,17 +218,22 @@
/*background-color: @egw_color_2_d;*/
h1 {
h1,h2 {
margin: 5px 0px 3px 5px;
padding: 0px 0px 0px 24px;
line-height: 1em;
.fontsize_l;
font-weight: normal;
background-image:url(../images/arrow_right.svg);
background-repeat:no-repeat;
background-position:left center;
background-size: 12px;
}
h2 {
padding-bottom: 2px;
}
div.egw_fw_ui_category:nth-last-of-type(-n+3) {
img.egw_fw_ui_sidemenu_listitem_icon {
display: block;
@ -255,7 +260,7 @@
margin-top: 4px;
background-color: @egw_color_2_a;
.color_5_gray;
h1 {
h1,h2 {
background-image:url(../images/arrow_down.svg);
line-height: 1em;
font-size: 12px;
@ -491,19 +496,18 @@
border-top-width: 0;
border-left: 0px solid;
border-bottom: 0px solid;
margin-left: 4px;
margin-left: 0px;
margin-top: 0px;
padding-bottom: 5px;
padding-left: 0px;
padding-top: 3px;
margin-right: 5px;
margin-right: 0px;
/*min-height: 50px;*/
// Last Element rounded
// Last Element
&:last-of-type{
.border_radius (0, 0, 10px, 0);
border-color: @gray_30;
margin-bottom: 5px;
margin-bottom: -2px;
}
img { .dimension_height_s; vertical-align: middle;}

View File

@ -4876,7 +4876,7 @@ td.message span.message {
background-color: #E6E6E6;
/*background-color: @egw_color_2_d;*/
}
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category h1 {
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category h2 {
margin: 5px 0px 3px 5px;
padding: 0px 0px 0px 24px;
line-height: 1em;
@ -4898,21 +4898,21 @@ td.message span.message {
background-color: #0C5DA5;
color: #f2f2f2;
}
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h1 {
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h2 {
background-image: url(../images/arrow_down.svg);
line-height: 1em;
font-size: 12px;
background-size: 12px;
filter: brightness(3);
}
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h1 a {
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h2 a {
color: #FFF;
}
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h1 a img {
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h2 a img {
width: 16px;
height: 16px;
}
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h1 a:hover {
#egw_fw_sidebar #egw_fw_sidemenu .egw_fw_ui_sidemenu_entry_content .egw_fw_ui_category_active h2 a:hover {
padding: 5px 30px 5px 0px;
width: 200px;
background-color: #f0f0f0;