update tabs
This commit is contained in:
parent
ce30e1391e
commit
93ebd18a5c
24 changed files with 602 additions and 316 deletions
|
@ -212,3 +212,8 @@
|
|||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.emby-button-foreground {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
94
dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.css
vendored
Normal file
94
dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.css
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
.emby-tab-button {
|
||||
background: transparent;
|
||||
border: 0 !important;
|
||||
cursor: pointer;
|
||||
outline: none !important;
|
||||
width: auto;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
color: #aaa !important;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
flex-shrink: 0;
|
||||
margin: 0;
|
||||
padding: 1.2em .9em;
|
||||
transition: none !important;
|
||||
position: relative;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold !important;
|
||||
height: auto;
|
||||
min-width: initial;
|
||||
line-height: initial;
|
||||
border-radius: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.emby-tab-button:focus {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.emby-tab-button-active {
|
||||
color: #52B54B !important;
|
||||
}
|
||||
|
||||
.emby-tabs-slider {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emby-tabs-selection-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
/* Need this or it will be partially covered by the drop-shadow on android */
|
||||
bottom: 1px;
|
||||
height: 2px;
|
||||
z-index: 1000;
|
||||
background: #52B54B;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.emby-tab-button-selection-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
border: 0;
|
||||
/* Need this or it will be partially covered by the drop-shadow on android */
|
||||
bottom: 1px;
|
||||
height: 2px;
|
||||
right: 0;
|
||||
border-radius: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.emby-tab-button-selection-bar-active {
|
||||
background: #52B54B;
|
||||
}
|
||||
|
||||
.emby-tab-button-ripple-effect {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
background: #181818 !important;
|
||||
animation: emby-tab-button-ripple-animation .8s !important;
|
||||
transform-origin: center center !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
@keyframes emby-tab-button-ripple-animation {
|
||||
0% {
|
||||
transform: scale(.2, 1);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: none;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: none;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
309
dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.js
vendored
Normal file
309
dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.js
vendored
Normal file
|
@ -0,0 +1,309 @@
|
|||
define(['dom', 'scroller', 'browser', 'registerElement', 'css!./emby-tabs', 'scrollStyles'], function (dom, scroller, browser) {
|
||||
|
||||
var EmbyTabs = Object.create(HTMLDivElement.prototype);
|
||||
var buttonClass = 'emby-tab-button';
|
||||
var activeButtonClass = buttonClass + '-active';
|
||||
|
||||
function getBoundingClientRect(elem) {
|
||||
|
||||
// Support: BlackBerry 5, iOS 3 (original iPhone)
|
||||
// If we don't have gBCR, just use 0,0 rather than error
|
||||
if (elem.getBoundingClientRect) {
|
||||
return elem.getBoundingClientRect();
|
||||
} else {
|
||||
return { top: 0, left: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
function getButtonSelectionBar(tabButton) {
|
||||
var elem = tabButton.querySelector('.' + buttonClass + '-selection-bar');
|
||||
|
||||
if (!elem) {
|
||||
elem = document.createElement('div');
|
||||
elem.classList.add(buttonClass + '-selection-bar');
|
||||
tabButton.appendChild(elem);
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function hideButtonSelectionBar(tabButton) {
|
||||
|
||||
var elem = getButtonSelectionBar(tabButton);
|
||||
|
||||
elem.classList.add('hide');
|
||||
elem.classList.remove('emby-tab-button-selection-bar-active');
|
||||
}
|
||||
|
||||
function showButtonSelectionBar(tabButton) {
|
||||
var elem = getButtonSelectionBar(tabButton);
|
||||
|
||||
elem.classList.remove('hide');
|
||||
elem.classList.add('emby-tab-button-selection-bar-active');
|
||||
}
|
||||
|
||||
function animtateSelectionBar(bar, start, pos, duration) {
|
||||
|
||||
var endTransform = pos ? ('translateX(' + pos + 'px)') : 'none';
|
||||
var startTransform = start ? ('translateX(' + start + 'px)') : 'none';
|
||||
|
||||
if (!duration || !bar.animate) {
|
||||
bar.style.transform = endTransform;
|
||||
return;
|
||||
}
|
||||
|
||||
bar.style.transform = startTransform;
|
||||
|
||||
var keyframes = [
|
||||
{ transform: 'translateX(' + start + 'px)', offset: 0 },
|
||||
{ transform: endTransform, offset: 1 }];
|
||||
|
||||
bar.animate(keyframes, {
|
||||
duration: duration,
|
||||
iterations: 1,
|
||||
easing: 'ease-out',
|
||||
fill: 'forwards'
|
||||
});
|
||||
}
|
||||
|
||||
function moveSelectionBar(tabs, newButton, oldButton, animate) {
|
||||
|
||||
if (oldButton) {
|
||||
hideButtonSelectionBar(oldButton);
|
||||
}
|
||||
hideButtonSelectionBar(newButton);
|
||||
|
||||
var selectionBar = tabs.selectionBar;
|
||||
|
||||
if (selectionBar) {
|
||||
selectionBar.style.width = newButton.offsetWidth + 'px';
|
||||
selectionBar.classList.remove('hide');
|
||||
}
|
||||
|
||||
var tabsOffset = getBoundingClientRect(tabs);
|
||||
var startOffset = tabs.currentOffset || 0;
|
||||
|
||||
if (oldButton) {
|
||||
if (tabs.scroller) {
|
||||
startOffset = tabs.scroller.getCenterPosition(oldButton);
|
||||
} else {
|
||||
startOffset = getBoundingClientRect(oldButton).left - tabsOffset.left;
|
||||
}
|
||||
}
|
||||
|
||||
var endPosition;
|
||||
if (tabs.scroller) {
|
||||
endPosition = tabs.scroller.getCenterPosition(newButton);
|
||||
} else {
|
||||
var tabButtonOffset = getBoundingClientRect(newButton);
|
||||
endPosition = tabButtonOffset.left - tabsOffset.left;
|
||||
}
|
||||
|
||||
var delay = animate ? 180 : 0;
|
||||
if (selectionBar) {
|
||||
animtateSelectionBar(selectionBar, startOffset, endPosition, delay);
|
||||
}
|
||||
tabs.currentOffset = endPosition;
|
||||
|
||||
newButton.classList.add(activeButtonClass);
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
showButtonSelectionBar(newButton);
|
||||
if (selectionBar) {
|
||||
selectionBar.classList.add('hide');
|
||||
}
|
||||
|
||||
}, delay);
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
|
||||
var tabs = this;
|
||||
|
||||
var current = tabs.querySelector('.' + activeButtonClass);
|
||||
var tabButton = dom.parentWithClass(e.target, buttonClass);
|
||||
|
||||
if (tabButton && tabButton != current) {
|
||||
|
||||
if (current) {
|
||||
current.classList.remove(activeButtonClass);
|
||||
}
|
||||
|
||||
var previousIndex = current ? parseInt(current.getAttribute('data-index')) : null;
|
||||
|
||||
moveSelectionBar(tabs, tabButton, current, true);
|
||||
var index = parseInt(tabButton.getAttribute('data-index'));
|
||||
|
||||
tabs.dispatchEvent(new CustomEvent("beforetabchange", {
|
||||
detail: {
|
||||
selectedTabIndex: index,
|
||||
previousIndex: previousIndex
|
||||
}
|
||||
}));
|
||||
|
||||
// If toCenter is called syncronously within the click event, it sometimes ends up canceling it
|
||||
setTimeout(function () {
|
||||
|
||||
tabs.selectedTabIndex = index;
|
||||
|
||||
tabs.dispatchEvent(new CustomEvent("tabchange", {
|
||||
detail: {
|
||||
selectedTabIndex: index,
|
||||
previousIndex: previousIndex
|
||||
}
|
||||
}));
|
||||
}, 120);
|
||||
|
||||
if (tabs.scroller) {
|
||||
tabs.scroller.toCenter(tabButton, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function initScroller(tabs) {
|
||||
|
||||
if (tabs.scroller) {
|
||||
return;
|
||||
}
|
||||
|
||||
var contentScrollSlider = tabs.querySelector('.emby-tabs-slider');
|
||||
if (contentScrollSlider) {
|
||||
tabs.scroller = new scroller(tabs, {
|
||||
horizontal: 1,
|
||||
itemNav: 0,
|
||||
mouseDragging: 1,
|
||||
touchDragging: 1,
|
||||
slidee: contentScrollSlider,
|
||||
smart: true,
|
||||
releaseSwing: true,
|
||||
scrollBy: 200,
|
||||
speed: 120,
|
||||
elasticBounds: 1,
|
||||
dragHandle: 1,
|
||||
dynamicHandle: 1,
|
||||
clickBar: 1,
|
||||
hiddenScroll: true,
|
||||
|
||||
// In safari the transform is causing the headers to occasionally disappear or flicker
|
||||
requireAnimation: !browser.safari
|
||||
});
|
||||
tabs.scroller.init();
|
||||
} else {
|
||||
tabs.classList.add('hiddenScrollX');
|
||||
}
|
||||
}
|
||||
|
||||
function initSelectionBar(tabs) {
|
||||
|
||||
var contentScrollSlider = tabs.querySelector('.emby-tabs-slider');
|
||||
|
||||
if (!contentScrollSlider) {
|
||||
return;
|
||||
}
|
||||
|
||||
var elem = document.createElement('div');
|
||||
elem.classList.add('emby-tabs-selection-bar');
|
||||
|
||||
contentScrollSlider.appendChild(elem);
|
||||
tabs.selectionBar = elem;
|
||||
}
|
||||
|
||||
EmbyTabs.createdCallback = function () {
|
||||
|
||||
if (this.classList.contains('emby-tabs')) {
|
||||
return;
|
||||
}
|
||||
this.classList.add('emby-tabs');
|
||||
|
||||
dom.addEventListener(this, 'click', onClick, {
|
||||
passive: true
|
||||
});
|
||||
|
||||
initSelectionBar(this);
|
||||
};
|
||||
|
||||
EmbyTabs.attachedCallback = function () {
|
||||
|
||||
initScroller(this);
|
||||
|
||||
var current = this.querySelector('.' + activeButtonClass);
|
||||
var currentIndex = current ? parseInt(current.getAttribute('data-index')) : 0;
|
||||
|
||||
var newTabButton = this.querySelectorAll('.' + buttonClass)[currentIndex];
|
||||
|
||||
if (newTabButton) {
|
||||
moveSelectionBar(this, newTabButton, current, false);
|
||||
}
|
||||
};
|
||||
|
||||
EmbyTabs.detachedCallback = function () {
|
||||
|
||||
if (this.scroller) {
|
||||
this.scroller.destroy();
|
||||
this.scroller = null;
|
||||
}
|
||||
|
||||
dom.removeEventListener(this, 'click', onClick, {
|
||||
passive: true
|
||||
});
|
||||
this.selectionBar = null;
|
||||
};
|
||||
|
||||
EmbyTabs.selectedIndex = function (selected) {
|
||||
|
||||
var tabs = this;
|
||||
|
||||
if (selected == null) {
|
||||
|
||||
return tabs.selectedTabIndex || 0;
|
||||
}
|
||||
|
||||
var current = tabs.selectedIndex();
|
||||
|
||||
tabs.selectedTabIndex = selected;
|
||||
|
||||
var tabButtons = tabs.querySelectorAll('.' + buttonClass);
|
||||
|
||||
if (current == selected) {
|
||||
|
||||
tabs.dispatchEvent(new CustomEvent("beforetabchange", {
|
||||
detail: {
|
||||
selectedTabIndex: selected
|
||||
}
|
||||
}));
|
||||
tabs.dispatchEvent(new CustomEvent("tabchange", {
|
||||
detail: {
|
||||
selectedTabIndex: selected
|
||||
}
|
||||
}));
|
||||
|
||||
moveSelectionBar(tabs, tabButtons[selected], tabButtons[selected], false);
|
||||
} else {
|
||||
tabButtons[selected].click();
|
||||
}
|
||||
};
|
||||
|
||||
EmbyTabs.triggerTabChange = function (selected) {
|
||||
|
||||
var tabs = this;
|
||||
|
||||
tabs.dispatchEvent(new CustomEvent("beforetabchange", {
|
||||
detail: {
|
||||
selectedTabIndex: tabs.selectedIndex()
|
||||
}
|
||||
}));
|
||||
|
||||
tabs.dispatchEvent(new CustomEvent("tabchange", {
|
||||
detail: {
|
||||
selectedTabIndex: tabs.selectedIndex()
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
document.registerElement('emby-tabs', {
|
||||
prototype: EmbyTabs,
|
||||
extends: 'div'
|
||||
});
|
||||
});
|
|
@ -475,6 +475,12 @@ define(['browser', 'layoutManager', 'dom', 'scrollStyles'], function (browser, l
|
|||
};
|
||||
};
|
||||
|
||||
self.getCenterPosition = function(item) {
|
||||
|
||||
var pos = self.getPos(item);
|
||||
return within(pos.center, pos.start, pos.end);
|
||||
};
|
||||
|
||||
/**
|
||||
* Slide SLIDEE by amount of pixels.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue