luci-base, themes: dropdown behaviour improvements
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
e35fb36ea5
commit
4791180eb3
3 changed files with 98 additions and 41 deletions
|
@ -1436,6 +1436,14 @@ if (window.NodeList && !NodeList.prototype.forEach) {
|
|||
};
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame = function(f) {
|
||||
window.setTimeout(function() {
|
||||
f(new Date().getTime())
|
||||
}, 1000/30);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var dummyElem, domParser;
|
||||
|
||||
|
@ -1556,11 +1564,10 @@ CBIDropdown = {
|
|||
var st = window.getComputedStyle(sb, null),
|
||||
ul = sb.querySelector('ul'),
|
||||
li = ul.querySelectorAll('li'),
|
||||
fl = findParent(sb, '.cbi-value-field'),
|
||||
sel = ul.querySelector('[selected]'),
|
||||
rect = sb.getBoundingClientRect(),
|
||||
h = sb.clientHeight - parseFloat(st.paddingTop) - parseFloat(st.paddingBottom),
|
||||
mh = this.dropdown_items * h,
|
||||
eh = Math.min(mh, li.length * h);
|
||||
items = Math.min(this.dropdown_items, li.length);
|
||||
|
||||
document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) {
|
||||
s.dispatchEvent(new CustomEvent('cbi-dropdown-close', {}));
|
||||
|
@ -1568,22 +1575,54 @@ CBIDropdown = {
|
|||
|
||||
sb.setAttribute('open', '');
|
||||
|
||||
if ('ontouchstart' in window) {
|
||||
var scroll = document.documentElement.scrollTop,
|
||||
vpWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
|
||||
vpHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
var pv = ul.cloneNode(true);
|
||||
pv.classList.add('preview');
|
||||
|
||||
ul.style.top = h + 'px';
|
||||
if (fl)
|
||||
fl.classList.add('cbi-dropdown-open');
|
||||
|
||||
if ('ontouchstart' in window) {
|
||||
var vpWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
|
||||
vpHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
|
||||
scrollFrom = window.pageYOffset,
|
||||
scrollTo = scrollFrom + rect.top - vpHeight * 0.5,
|
||||
start = null;
|
||||
|
||||
ul.style.top = sb.offsetHeight + 'px';
|
||||
ul.style.left = -rect.left + 'px';
|
||||
ul.style.right = (rect.right - vpWidth) + 'px';
|
||||
ul.style.maxHeight = (vpHeight * 0.5) + 'px';
|
||||
ul.style.WebkitOverflowScrolling = 'touch';
|
||||
|
||||
window.scrollTo(0, (scroll + rect.top - vpHeight * 0.6));
|
||||
var scrollStep = function(timestamp) {
|
||||
if (!start) {
|
||||
start = timestamp;
|
||||
ul.scrollTop = sel ? Math.max(sel.offsetTop - sel.offsetHeight, 0) : 0;
|
||||
}
|
||||
|
||||
var duration = Math.max(timestamp - start, 1);
|
||||
if (duration < 100) {
|
||||
document.body.scrollTop = scrollFrom + (scrollTo - scrollFrom) * (duration / 100);
|
||||
window.requestAnimationFrame(scrollStep);
|
||||
}
|
||||
else {
|
||||
document.body.scrollTop = scrollTo;
|
||||
}
|
||||
};
|
||||
|
||||
window.requestAnimationFrame(scrollStep);
|
||||
}
|
||||
else {
|
||||
ul.style.maxHeight = mh + 'px';
|
||||
ul.scrollTop = sel ? Math.max(sel.offsetTop - sel.offsetHeight, 0) : 0;
|
||||
ul.style.maxHeight = '1px';
|
||||
ul.style.top = ul.style.bottom = '';
|
||||
ul.style[((rect.top + rect.height + eh) > window.innerHeight) ? 'bottom' : 'top'] = rect.height + 'px';
|
||||
|
||||
window.requestAnimationFrame(function() {
|
||||
var height = items * li[Math.max(0, li.length - 2)].offsetHeight;
|
||||
|
||||
ul.scrollTop = sel ? Math.max(sel.offsetTop - sel.offsetHeight, 0) : 0;
|
||||
ul.style[((rect.top + rect.height + height) > window.innerHeight) ? 'bottom' : 'top'] = rect.height + 'px';
|
||||
ul.style.maxHeight = height + 'px';
|
||||
});
|
||||
}
|
||||
|
||||
ul.querySelectorAll('[selected] input[type="checkbox"]').forEach(function(c) {
|
||||
|
@ -1592,10 +1631,6 @@ CBIDropdown = {
|
|||
|
||||
ul.classList.add('dropdown');
|
||||
|
||||
var pv = ul.cloneNode(true);
|
||||
pv.classList.remove('dropdown');
|
||||
pv.classList.add('preview');
|
||||
|
||||
sb.insertBefore(pv, ul.nextElementSibling);
|
||||
|
||||
li.forEach(function(l) {
|
||||
|
@ -1613,7 +1648,8 @@ CBIDropdown = {
|
|||
|
||||
var pv = sb.querySelector('ul.preview'),
|
||||
ul = sb.querySelector('ul.dropdown'),
|
||||
li = ul.querySelectorAll('li');
|
||||
li = ul.querySelectorAll('li'),
|
||||
fl = findParent(sb, '.cbi-value-field');
|
||||
|
||||
li.forEach(function(l) { l.removeAttribute('tabindex'); });
|
||||
sb.lastElementChild.removeAttribute('tabindex');
|
||||
|
@ -1623,6 +1659,10 @@ CBIDropdown = {
|
|||
sb.style.width = sb.style.height = '';
|
||||
|
||||
ul.classList.remove('dropdown');
|
||||
ul.style.top = ul.style.bottom = ul.style.maxHeight = '';
|
||||
|
||||
if (fl)
|
||||
fl.classList.remove('cbi-dropdown-open');
|
||||
|
||||
if (!no_focus)
|
||||
this.setFocus(sb, sb);
|
||||
|
@ -1817,14 +1857,13 @@ CBIDropdown = {
|
|||
|
||||
createItems: function(sb, value) {
|
||||
var sbox = this,
|
||||
val = (value || '').trim().split(/\s+/),
|
||||
val = (value || '').trim(),
|
||||
ul = sb.querySelector('ul');
|
||||
|
||||
if (!sbox.multi)
|
||||
val.length = Math.min(val.length, 1);
|
||||
|
||||
if (val.length === 1 && val[0].length === 0)
|
||||
val.length = 0;
|
||||
val = val.length ? [ val ] : [];
|
||||
else
|
||||
val = val.length ? val.split(/\s+/) : [];
|
||||
|
||||
val.forEach(function(item) {
|
||||
var new_item = null;
|
||||
|
@ -1881,6 +1920,8 @@ CBIDropdown = {
|
|||
var li = findParent(ev.target, 'li');
|
||||
if (li && li.parentNode.classList.contains('dropdown'))
|
||||
this.toggleItem(sb, li);
|
||||
else if (li && li.parentNode.classList.contains('preview'))
|
||||
this.closeDropdown(sb);
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
|
|
|
@ -60,7 +60,6 @@ blockquote:after {
|
|||
}
|
||||
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
font-size: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
|
@ -1457,6 +1456,7 @@ footer {
|
|||
max-width: none;
|
||||
min-width: 100%;
|
||||
width: auto;
|
||||
transition: max-height .125s ease-in;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul > li[display],
|
||||
|
|
|
@ -491,16 +491,16 @@ select:hover {
|
|||
|
||||
input[type=text],
|
||||
input[type=password] {
|
||||
padding: 0 3px;
|
||||
padding: .25em;
|
||||
}
|
||||
|
||||
select,
|
||||
input[type=text],
|
||||
input[type=password] {
|
||||
input[type=password],
|
||||
.cbi-dropdown {
|
||||
width: 20em;
|
||||
font-size: inherit;
|
||||
line-height: 13pt;
|
||||
height: 14pt;
|
||||
font-size: 10pt;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
select[multiple] {
|
||||
|
@ -521,7 +521,6 @@ input.cbi-input-password + img {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.td [data-dynlist] > input,
|
||||
.td input.cbi-input-password {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
@ -1050,6 +1049,7 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
font-weight: bold;
|
||||
text-shadow: 1px 1px 0px #fff;
|
||||
display: none;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul > li {
|
||||
|
@ -1062,7 +1062,7 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
flex-grow: 1;
|
||||
align-items: center;
|
||||
align-self: center;
|
||||
min-height: 20px;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul > li .hide-open { display: initial; }
|
||||
|
@ -1092,10 +1092,6 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul > li input[type="text"] {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -1110,6 +1106,7 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
max-width: none;
|
||||
min-width: 100%;
|
||||
width: auto;
|
||||
transition: max-height .125s ease-in;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul > li[display],
|
||||
|
@ -1125,7 +1122,6 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
}
|
||||
|
||||
.cbi-dropdown[empty] > ul > li,
|
||||
.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder],
|
||||
.cbi-dropdown[multiple][open] > ul.dropdown > li > form {
|
||||
display: block;
|
||||
}
|
||||
|
@ -1213,9 +1209,9 @@ select + .cbi-button {
|
|||
padding: 0 6px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
height: 14pt;
|
||||
height: 22px;
|
||||
font-size: 10pt;
|
||||
line-height: 12pt;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.cbi-tooltip-container {
|
||||
|
@ -1240,6 +1236,7 @@ select + .cbi-button {
|
|||
left: auto;
|
||||
opacity: 1;
|
||||
transition: opacity .25s ease-in;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.zonebadge .cbi-tooltip {
|
||||
|
@ -1652,6 +1649,10 @@ select + .cbi-button {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
.td.cbi-dropdown-open {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.td select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
@ -1734,26 +1735,41 @@ select + .cbi-button {
|
|||
font-size: 12pt;
|
||||
}
|
||||
|
||||
input, textarea, select {
|
||||
input, textarea, select, .cbi-button {
|
||||
font-size: 12pt !important;
|
||||
line-height: 1.4em;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
select, input[type="text"], input[type="password"] {
|
||||
width: 100%;
|
||||
height: 1.4em;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
input.cbi-input-password {
|
||||
input[type="text"] + .cbi-button,
|
||||
input[type="password"] + .cbi-button,
|
||||
select + .cbi-button {
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
input.cbi-input-password,
|
||||
[data-dynlist] > .add-item > input {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.cbi-dynlist,
|
||||
.cbi-dropdown {
|
||||
min-width: 100%;
|
||||
height: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cbi-dropdown > .more,
|
||||
.cbi-dropdown > ul > li,
|
||||
.cbi-dropdown > ul > li[placeholder] {
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.btn, .cbi-button {
|
||||
font-size: 9pt !important;
|
||||
line-height: 13pt;
|
||||
|
|
Loading…
Reference in a new issue