[refactor] improve menu tab index

This commit is contained in:
Kombie 2020-03-09 08:39:25 +00:00 committed by GitHub
parent e8a29d9bc1
commit 65e84f4470
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 228 additions and 136 deletions

View File

@ -86,7 +86,7 @@
border-radius: 0;
}
.menu-nav-body {
.menu-subnav {
display: none;
}
@ -115,7 +115,7 @@
}
.menu-content-item {
padding: calc(var(--menu-space) * 1) calc(var(--menu-space) * 2);
padding: calc(var(--menu-space) * 3);
position: relative;
z-index: 1;
}
@ -215,7 +215,7 @@
justify-content: flex-start;
}
.menu-nav-body {
.menu-subnav {
background-color: rgb(var(--theme-color-02));
display: flex;
flex-direction: column;
@ -225,11 +225,11 @@
transition: height var(--layout-timing-extra-fast);
}
.menu-nav-body.active {
height: var(--menu-nav-body-height);
.menu-subnav.active {
height: var(--menu-subnav-height);
}
.is-edge .menu-nav-body {
.is-edge .menu-subnav {
background-color: rgba(var(--theme-color-02), 0.5);
}

View File

@ -5,12 +5,12 @@
<div class="menu-item-form">
<div class="form-wrap">
<input id="control-link-item-display-name-show" class="control-link-item-display-name-show" type="checkbox" tabindex="-1">
<label for="control-link-item-display-name-show"><span class="label-icon"></span> Name</label>
<label for="control-link-item-display-name-show"><span class="label-icon"></span> Show</label>
</div>
<div class="form-wrap">
<div class="form-indent">
<div class="form-wrap">
<label for="control-link-item-display-name-size-range">Name size</label>
<label for="control-link-item-display-name-size-range">Size</label>
<div class="form-group form-group-block">
<input id="control-link-item-display-name-size-range" class="control-link-item-display-name-size-range mr-3" type="range" value="0" tabindex="-1">
<input class="control-link-item-display-name-size-number form-group-item-medium form-group-radius-left" type="number" value="0" tabindex="-1">

View File

@ -10,7 +10,7 @@
<div class="form-wrap">
<div class="form-indent">
<div class="form-wrap">
<label for="control-group-name-size-range">Name Size</label>
<label for="control-group-name-size-range">Size</label>
<div class="form-group form-group-block">
<input id="control-group-name-size-range" class="control-group-name-size-range mr-3" type="range" value="0" tabindex="-1">
<input class="control-group-name-size-number form-group-item-medium form-group-radius-left" type="number" value="0" tabindex="-1">

View File

@ -5,7 +5,7 @@
<div class="menu-item-form">
<div class="form-wrap">
<input id="control-header-coloraccent-show" class="control-header-coloraccent-show" type="checkbox" tabindex="-1">
<label for="control-header-coloraccent-show"><span class="label-icon"></span> Show Colour/Accent</label>
<label for="control-header-coloraccent-show"><span class="label-icon"></span> Show</label>
</div>
<div class="form-helper">
<p class="control-header-coloraccent-show-helper form-helper-item">Colour and Accent can also be found under Theme.</p>

View File

@ -5,7 +5,7 @@
<div class="menu-item-form">
<div class="form-wrap">
<input id="control-header-editadd-show" class="control-header-editadd-show" type="checkbox" tabindex="-1">
<label for="control-header-editadd-show"><span class="label-icon"></span> Show Edit/Add</label>
<label for="control-header-editadd-show"><span class="label-icon"></span> Show</label>
</div>
<div class="form-wrap">
<div class="form-indent">

View File

@ -10,7 +10,7 @@
<div class="form-wrap">
<div class="form-indent">
<div class="form-wrap">
<label class="control-header-search-width-by-label">Search box width</label>
<label class="control-header-search-width-by-label">Width</label>
</div>
<div class="form-wrap">
<input id="control-header-search-width-by-auto" class="control-header-search-width-by-auto" type="radio" name="control-header-search-width" value="auto" tabindex="-1">

View File

@ -5,7 +5,7 @@
<div class="menu-item-form">
<div class="form-sticky">
<div class="form-wrap">
<p>Colour shades</p>
<p>Shades</p>
</div>
<div class="form-wrap">
<div class="form-group form-group-block form-group-border form-group-border-theme-color">

View File

@ -4,7 +4,7 @@
</div>
<div class="menu-item-form">
<div class="form-wrap">
<label for="control-theme-font-display-name">Display font</label>
<label for="control-theme-font-display-name">Display</label>
<div class="form-group form-group-block">
<input id="control-theme-font-display-name" class="control-theme-font-display-name" type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Google font name" tabindex="-1">
<button class="control-theme-font-display-name-default button" tabindex="-1" title="Reset to default"><span class="icon-replay"></span></button>
@ -23,7 +23,7 @@
<div class="form-indent">
<hr>
<div class="form-wrap">
<label for="control-theme-font-display-weight-range">Font weight</label>
<label for="control-theme-font-display-weight-range">Weight</label>
<div class="form-group form-group-block">
<input id="control-theme-font-display-weight-range" class="control-theme-font-display-weight-range mr-3" type="range" value="0" tabindex="-1">
<input class="control-theme-font-display-weight-number form-group-item-medium form-group-radius-left" type="number" value="0" tabindex="-1">
@ -42,7 +42,7 @@
</div>
<hr>
<div class="form-wrap">
<label>Font style</label>
<label>Style</label>
</div>
<div class="form-inline">
<div class="form-inline form-inline-spacer">
@ -64,7 +64,7 @@
<hr>
<div class="form-wrap">
<div class="form-wrap">
<label for="control-theme-font-ui-name">UI font</label>
<label for="control-theme-font-ui-name">UI</label>
<div class="form-group form-group-block">
<input id="control-theme-font-ui-name" class="control-theme-font-ui-name" type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Google font name" tabindex="-1">
<button class="control-theme-font-ui-name-default button" tabindex="-1" title="Reset to default"><span class="icon-replay"></span></button>
@ -84,7 +84,7 @@
<div class="form-indent">
<hr>
<div class="form-wrap">
<label for="control-theme-font-ui-weight">Font weight</label>
<label for="control-theme-font-ui-weight">Weight</label>
<div class="form-group form-group-block">
<input id="control-theme-font-ui-weight-range" class="control-theme-font-ui-weight-range mr-3" type="range" value="0" tabindex="-1">
<input class="control-theme-font-ui-weight-number form-group-item-medium form-group-radius-left" type="number" value="0" tabindex="-1">
@ -103,7 +103,7 @@
</div>
<hr>
<div class="form-wrap">
<label>Font style</label>
<label>Style</label>
</div>
<div class="form-inline">
<div class="form-inline form-inline-spacer">

View File

@ -1,7 +1,7 @@
<div class="menu-nav">
<div class="menu-nav-item">
<button class="control-menu-layout menu-nav-tab button active" tabindex="-1">Layout</button>
<div class="menu-nav-body menu-nav-body-layout active">
<button class="control-menu-layout menu-nav-tab button" tabindex="-1">Layout</button>
<div class="menu-subnav menu-subnav-layout">
<a href="#menu-content-layout-scaling" class="menu-nav-sub button button-small" tabindex="-1">Scaling</a>
<a href="#menu-content-layout-area" class="menu-nav-sub button button-small" tabindex="-1">Area</a>
<a href="#menu-content-layout-alignment" class="menu-nav-sub button button-small" tabindex="-1">Alignment</a>
@ -12,7 +12,7 @@
</div>
<div class="menu-nav-item">
<button class="control-menu-header menu-nav-tab button" tabindex="-1">Header</button>
<div class="menu-nav-body menu-nav-body-header active">
<div class="menu-subnav menu-subnav-header">
<a href="#menu-content-header-area" class="menu-nav-sub button button-small" tabindex="-1">Area</a>
<a href="#menu-content-header-alignment" class="menu-nav-sub button button-small" tabindex="-1">Alignment</a>
<a href="#menu-content-header-order" class="menu-nav-sub button button-small" tabindex="-1">Order</a>
@ -31,7 +31,7 @@
</div>
<div class="menu-nav-item">
<button class="control-menu-bookmarks menu-nav-tab button" tabindex="-1">Bookmarks</button>
<div class="menu-nav-body menu-nav-body-bookmarks active">
<div class="menu-subnav menu-subnav-bookmarks">
<a href="#menu-content-bookmarks-area" class="menu-nav-sub button button-small" tabindex="-1">Area</a>
<a href="#menu-content-bookmarks-alignment" class="menu-nav-sub button button-small" tabindex="-1">Alignment</a>
<a href="#menu-content-bookmarks-bookmarks" class="menu-nav-sub button button-small" tabindex="-1">Bookmarks</a>
@ -48,7 +48,7 @@
</div>
<div class="menu-nav-item">
<button class="control-menu-groups menu-nav-tab button" tabindex="-1">Groups</button>
<div class="menu-nav-body menu-nav-body-groups active">
<div class="menu-subnav menu-subnav-groups">
<a href="#menu-content-groups-area" class="menu-nav-sub button button-small" tabindex="-1">Area</a>
<a href="#menu-content-groups-order" class="menu-nav-sub button button-small" tabindex="-1">Order</a>
<a href="#menu-content-groups-names" class="menu-nav-sub button button-small" tabindex="-1">Names</a>
@ -58,7 +58,7 @@
</div>
<div class="menu-nav-item">
<button class="control-menu-theme menu-nav-tab button" tabindex="-1">Theme</button>
<div class="menu-nav-body menu-nav-body-theme active">
<div class="menu-subnav menu-subnav-theme">
<a href="#menu-content-theme-preset" class="menu-nav-sub button button-small" tabindex="-1">Preset</a>
<a href="#menu-content-theme-saved" class="menu-nav-sub button button-small" tabindex="-1">Saved</a>
<a href="#menu-content-theme-style" class="menu-nav-sub button button-small" tabindex="-1">Style</a>
@ -72,14 +72,14 @@
</div>
<div class="menu-nav-item">
<button class="control-menu-background menu-nav-tab button" tabindex="-1">Background</button>
<div class="menu-nav-body menu-nav-body-background active">
<div class="menu-subnav menu-subnav-background">
<a href="#menu-content-background-color" class="menu-nav-sub button button-small" tabindex="-1">Colour</a>
<a href="#menu-content-background-image" class="menu-nav-sub button button-small" tabindex="-1">Image</a>
</div>
</div>
<div class="menu-nav-item">
<button class="control-menu-data menu-nav-tab button" tabindex="-1">Data</button>
<div class="menu-nav-body menu-nav-body-data active">
<div class="menu-subnav menu-subnav-data">
<a href="#menu-content-data-restore" class="menu-nav-sub button button-small" tabindex="-1">Restore</a>
<a href="#menu-content-data-backup" class="menu-nav-sub button button-small" tabindex="-1">Backup</a>
<a href="#menu-content-data-clear" class="menu-nav-sub button button-small" tabindex="-1">Clear</a>

View File

@ -1,5 +1,31 @@
var menu = (function() {
var bind = {};
bind.focus = {
loop: function(event) {
var firstElement = helper.e(".control-menu-layout");
var lastElement = helper.e(".menu-close-tab");
if (event.keyCode == 9 && event.shiftKey) {
if (document.activeElement === firstElement) {
lastElement.focus();
event.preventDefault();
}
} else if (event.keyCode == 9) {
if (document.activeElement === lastElement) {
firstElement.focus();
event.preventDefault();
}
};
},
add: function() {
window.addEventListener("keydown", bind.focus.loop, false);
},
remove: function() {
window.removeEventListener("keydown", bind.focus.loop, false);
}
};
var mod = {};
mod.open = function() {
@ -18,85 +44,137 @@ var menu = (function() {
});
};
var render = {};
mod.nav = {
state: {
layout: true,
header: false,
bookmarks: false,
groups: false,
theme: false,
background: false,
data: false,
coffee: false,
nighttab: false
},
toggle: function(name) {
for (var key in mod.nav.state) {
mod.nav.state[key] = false;
};
mod.nav.state[name] = true;
}
};
render.scrollToTop = function(name) {
render = {};
render.panel = function() {
if (state.get.current().menu) {
helper.addClass(helper.e("html"), "is-menu-open");
} else {
helper.removeClass(helper.e("html"), "is-menu-open");
};
};
render.nav = {
active: function() {
for (var key in mod.nav.state) {
if (mod.nav.state[key]) {
helper.removeClass(helper.e(".menu-content-" + key), "is-hidden");
} else {
helper.addClass(helper.e(".menu-content-" + key), "is-hidden");
};
};
},
tabindex: function() {
var menu = helper.e(".menu");
var menuCloseTab = helper.e(".menu-close-tab");
var allMenuContent = helper.eA(".menu-content");
allMenuContent.forEach(function(arrayItem, index) {
arrayItem.querySelectorAll("[tabindex]").forEach(function(arrayItem, index) {
if (state.get.current().menu) {
arrayItem.tabIndex = 1;
} else {
arrayItem.tabIndex = -1;
};
});
});
if (state.get.current().menu) {
menu.tabIndex = 1;
menuCloseTab.tabIndex = 2;
} else {
menu.tabIndex = -1;
menuCloseTab.tabIndex = -1;
};
},
scroll: function() {
if (window.innerWidth < 700) {
helper.e(".menu-area").scrollTop = 0;
} else {
if (name) {
helper.e(".menu-content-" + name).scrollTop = 0;
} else {
var allMenuContentArea = helper.eA(".menu-content");
allMenuContentArea.forEach(function(arrayItem, index) {
arrayItem.scrollTop = 0;
});
for (var key in mod.nav.state) {
if (mod.nav.state[key]) {
helper.e(".menu-content-" + key).scrollTop = 0;
};
};
};
render.nav = function(name) {
var allMenuNavTab = helper.eA(".menu-nav-tab");
var allMenuContentArea = helper.eA(".menu-content");
allMenuNavTab.forEach(function(arrayItem, index) {
helper.removeClass(arrayItem, "active");
});
allMenuContentArea.forEach(function(arrayItem, index) {
helper.addClass(arrayItem, "is-hidden");
});
var control = helper.e(".control-menu-" + name);
var content = helper.e(".menu-content-" + name);
if (control) {
helper.addClass(control, "active");
};
if (content) {
helper.removeClass(content, "is-hidden");
};
};
render.subnav = {
calculate: function() {
var allMenuNavBody = helper.eA(".menu-nav-body");
allMenuNavBody.forEach(function(arrayItem, index) {
arrayItem.setAttribute("style", "--menu-nav-body-height:" + arrayItem.getBoundingClientRect().height + "px;");
if (index > 0) {
helper.removeClass(arrayItem, "active");
};
});
},
toggle: function(name) {
var allMenuNavBody = helper.eA(".menu-nav-body");
allMenuNavBody.forEach(function(arrayItem, index) {
helper.removeClass(arrayItem, "active");
});
var body = helper.e(".menu-nav-body-" + name);
if (body) {
helper.addClass(body, "active");
};
}
};
render.tabindex = {
toggle: function() {
var menu = helper.e(".menu");
render.tab = {
active: function() {
for (var key in mod.nav.state) {
var controlMenu = helper.e(".control-menu-" + key);
if (mod.nav.state[key]) {
helper.addClass(controlMenu, "active");
} else {
helper.removeClass(controlMenu, "active");
};
};
},
tabindex: function() {
var allMenuNavTab = helper.eA(".menu-nav-tab");
allMenuNavTab.forEach(function(arrayItem, index) {
if (state.get.current().menu) {
menu.tabIndex = 1;
menu.querySelectorAll("[tabindex]").forEach(function(arrayItem, index) {
if (arrayItem.tabIndex == -1) {
arrayItem.tabIndex = 1;
} else {
arrayItem.tabIndex = -1;
};
});
}
};
render.subnav = {
active: function() {
for (var key in mod.nav.state) {
var menuSubnav = helper.e(".menu-subnav-" + key);
if (menuSubnav) {
if (mod.nav.state[key]) {
helper.addClass(menuSubnav, "active");
} else {
helper.removeClass(menuSubnav, "active");
};
};
};
},
tabindex: function() {
for (var key in mod.nav.state) {
var menuNavBody = helper.e(".menu-subnav-" + key);
if (menuNavBody) {
menuNavBody.querySelectorAll("[tabindex]").forEach(function(arrayItem, index) {
if (mod.nav.state[key] && state.get.current().menu) {
arrayItem.tabIndex = 1;
} else {
menu.tabIndex = -1;
menu.querySelectorAll("[tabindex]").forEach(function(arrayItem, index) {
if (arrayItem.tabIndex == 1) {
arrayItem.tabIndex = -1;
};
});
};
};
},
height: function() {
var allMenuNavBody = helper.eA(".menu-subnav");
allMenuNavBody.forEach(function(arrayItem, index) {
helper.addClass(arrayItem, "active");
arrayItem.setAttribute("style", "--menu-subnav-height:" + arrayItem.getBoundingClientRect().height + "px;");
helper.removeClass(arrayItem, "active");
});
}
};
@ -104,22 +182,62 @@ var menu = (function() {
helper.e(".menu").focus();
};
render.open = function() {
helper.addClass(helper.e("html"), "is-menu-open");
};
render.close = function() {
helper.removeClass(helper.e("html"), "is-menu-open");
};
render.removeStyle = function() {
helper.e(".menu").removeAttribute("style");
};
var nav = function(name) {
render.nav(name);
render.subnav.toggle(name);
render.scrollToTop(name);
mod.nav.toggle(name);
render.nav.active();
render.nav.tabindex();
render.tab.active();
render.tab.tabindex();
render.subnav.active();
render.subnav.tabindex();
render.nav.scroll(name);
};
var open = function() {
mod.open();
render.panel();
render.focus();
render.nav.active();
render.nav.tabindex();
render.tab.active();
render.tab.tabindex();
render.subnav.active();
render.subnav.tabindex();
render.nav.scroll(name);
bind.focus.add();
shade.open({
action: function() {
mod.close();
render.panel();
render.nav.active();
render.nav.tabindex();
render.tab.active();
render.tab.tabindex();
render.subnav.active();
render.subnav.tabindex();
bind.focus.remove();
pagelock.unlock();
}
});
pagelock.lock();
};
var close = function() {
mod.close();
render.panel();
render.nav.active();
render.nav.tabindex();
render.tab.active();
render.tab.tabindex();
render.subnav.active();
render.subnav.tabindex();
bind.focus.remove();
shade.close();
pagelock.unlock();
};
var toggle = function() {
@ -130,36 +248,10 @@ var menu = (function() {
};
};
var open = function() {
mod.open();
render.open();
render.focus();
render.scrollToTop();
render.tabindex.toggle();
shade.open({
action: function() {
mod.close();
render.close();
render.tabindex.toggle();
pagelock.unlock();
}
});
pagelock.lock();
};
var close = function() {
mod.close();
render.close();
render.tabindex.toggle();
shade.close();
pagelock.unlock();
};
var init = function() {
mod.close();
render.close();
render.removeStyle();
render.subnav.calculate();
render.subnav.height();
};
return {