mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Scrollable tabs 👍
This commit is contained in:
parent
1866c9c7ef
commit
e4626ee52b
@ -17,15 +17,58 @@
|
|||||||
|
|
||||||
|
|
||||||
RED.tabs = (function() {
|
RED.tabs = (function() {
|
||||||
|
|
||||||
|
|
||||||
function createTabs(options) {
|
function createTabs(options) {
|
||||||
var tabs = {};
|
var tabs = {};
|
||||||
var currentTabWidth;
|
var currentTabWidth;
|
||||||
var currentActiveTabWidth = 0;
|
var currentActiveTabWidth = 0;
|
||||||
|
|
||||||
var ul = $("#"+options.id);
|
var ul = $("#"+options.id);
|
||||||
ul.addClass("red-ui-tabs");
|
var wrapper = ul.wrap( "<div>" ).parent();
|
||||||
|
var scrollContainer = ul.wrap( "<div>" ).parent();
|
||||||
|
wrapper.addClass("red-ui-tabs");
|
||||||
|
if (options.addButton && typeof options.addButton === 'function') {
|
||||||
|
wrapper.addClass("red-ui-tabs-add");
|
||||||
|
var addButton = $('<div class="red-ui-tab-button"><a href="#"><i class="fa fa-plus"></i></a></div>').appendTo(wrapper);
|
||||||
|
addButton.find('a').click(function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
options.addButton();
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
var scrollLeft;
|
||||||
|
var scrollRight;
|
||||||
|
|
||||||
|
if (options.scrollable) {
|
||||||
|
wrapper.addClass("red-ui-tabs-scrollable");
|
||||||
|
scrollContainer.addClass("red-ui-tabs-scroll-container");
|
||||||
|
scrollContainer.scroll(updateScroll);
|
||||||
|
scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a");
|
||||||
|
scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') });
|
||||||
|
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
|
||||||
|
scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') });
|
||||||
|
}
|
||||||
|
function scrollEventHandler(evt,dir) {
|
||||||
|
evt.preventDefault();
|
||||||
|
if ($(this).hasClass('disabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var currentScrollLeft = scrollContainer.scrollLeft();
|
||||||
|
scrollContainer.animate( { scrollLeft: dir }, 300);
|
||||||
|
var interval = setInterval(function() {
|
||||||
|
var newScrollLeft = scrollContainer.scrollLeft()
|
||||||
|
if (newScrollLeft === currentScrollLeft) {
|
||||||
|
clearInterval(interval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentScrollLeft = newScrollLeft;
|
||||||
|
scrollContainer.animate( { scrollLeft: dir }, 300);
|
||||||
|
},300);
|
||||||
|
$(this).one('mouseup',function() {
|
||||||
|
clearInterval(interval);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ul.children().first().addClass("active");
|
ul.children().first().addClass("active");
|
||||||
ul.children().addClass("red-ui-tab");
|
ul.children().addClass("red-ui-tab");
|
||||||
|
|
||||||
@ -34,6 +77,23 @@ RED.tabs = (function() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateScroll() {
|
||||||
|
if (ul.children().length !== 0) {
|
||||||
|
var sl = scrollContainer.scrollLeft();
|
||||||
|
var scWidth = scrollContainer.width();
|
||||||
|
var ulWidth = ul.width();
|
||||||
|
if (sl === 0) {
|
||||||
|
scrollLeft.hide();
|
||||||
|
} else {
|
||||||
|
scrollLeft.show();
|
||||||
|
}
|
||||||
|
if (sl === ulWidth-scWidth) {
|
||||||
|
scrollRight.hide();
|
||||||
|
} else {
|
||||||
|
scrollRight.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
function onTabDblClick() {
|
function onTabDblClick() {
|
||||||
if (options.ondblclick) {
|
if (options.ondblclick) {
|
||||||
options.ondblclick(tabs[$(this).attr('href').slice(1)]);
|
options.ondblclick(tabs[$(this).attr('href').slice(1)]);
|
||||||
@ -49,6 +109,14 @@ RED.tabs = (function() {
|
|||||||
ul.children().removeClass("active");
|
ul.children().removeClass("active");
|
||||||
ul.children().css({"transition": "width 100ms"});
|
ul.children().css({"transition": "width 100ms"});
|
||||||
link.parent().addClass("active");
|
link.parent().addClass("active");
|
||||||
|
if (options.scrollable) {
|
||||||
|
var pos = link.parent().position().left;
|
||||||
|
if (pos-21 < 0) {
|
||||||
|
scrollContainer.animate( { scrollLeft: '+='+(pos-50) }, 300);
|
||||||
|
} else if (pos + 120 > scrollContainer.width()) {
|
||||||
|
scrollContainer.animate( { scrollLeft: '+='+(pos + 140-scrollContainer.width()) }, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (options.onchange) {
|
if (options.onchange) {
|
||||||
options.onchange(tabs[link.attr('href').slice(1)]);
|
options.onchange(tabs[link.attr('href').slice(1)]);
|
||||||
}
|
}
|
||||||
@ -61,23 +129,29 @@ RED.tabs = (function() {
|
|||||||
|
|
||||||
function updateTabWidths() {
|
function updateTabWidths() {
|
||||||
var tabs = ul.find("li.red-ui-tab");
|
var tabs = ul.find("li.red-ui-tab");
|
||||||
var width = ul.width();
|
var width = wrapper.width();
|
||||||
var tabCount = tabs.size();
|
var tabCount = tabs.size();
|
||||||
var tabWidth = (width-12-(tabCount*6))/tabCount;
|
var tabWidth = (width-12-(tabCount*6))/tabCount;
|
||||||
currentTabWidth = 100*tabWidth/width;
|
currentTabWidth = (100*tabWidth/width)+"%";
|
||||||
currentActiveTabWidth = currentTabWidth+"%";
|
currentActiveTabWidth = currentTabWidth+"%";
|
||||||
|
if (options.scrollable) {
|
||||||
if (options.hasOwnProperty("minimumActiveTabWidth")) {
|
tabWidth = Math.max(tabWidth,140);
|
||||||
|
currentTabWidth = tabWidth+"px";
|
||||||
|
currentActiveTabWidth = 0;
|
||||||
|
var listWidth = Math.max(wrapper.width(),12+(tabWidth+6)*tabCount);
|
||||||
|
ul.width(listWidth);
|
||||||
|
updateScroll();
|
||||||
|
} else if (options.hasOwnProperty("minimumActiveTabWidth")) {
|
||||||
if (tabWidth < options.minimumActiveTabWidth) {
|
if (tabWidth < options.minimumActiveTabWidth) {
|
||||||
tabCount -= 1;
|
tabCount -= 1;
|
||||||
tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount;
|
tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount;
|
||||||
currentTabWidth = 100*tabWidth/width;
|
currentTabWidth = (100*tabWidth/width)+"%";
|
||||||
currentActiveTabWidth = options.minimumActiveTabWidth+"px";
|
currentActiveTabWidth = options.minimumActiveTabWidth+"px";
|
||||||
} else {
|
} else {
|
||||||
currentActiveTabWidth = 0;
|
currentActiveTabWidth = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tabs.css({width:currentTabWidth+"%"});
|
tabs.css({width:currentTabWidth});
|
||||||
if (tabWidth < 50) {
|
if (tabWidth < 50) {
|
||||||
ul.find(".red-ui-tab-close").hide();
|
ul.find(".red-ui-tab-close").hide();
|
||||||
ul.find(".red-ui-tab-icon").hide();
|
ul.find(".red-ui-tab-icon").hide();
|
||||||
@ -97,7 +171,9 @@ RED.tabs = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick);
|
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick);
|
||||||
|
setTimeout(function() {
|
||||||
updateTabWidths();
|
updateTabWidths();
|
||||||
|
},0);
|
||||||
|
|
||||||
|
|
||||||
function removeTab(id) {
|
function removeTab(id) {
|
||||||
@ -210,8 +286,6 @@ RED.tabs = (function() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(ui.position.left,ui.offset.left);
|
|
||||||
},
|
},
|
||||||
stop: function(event,ui) {
|
stop: function(event,ui) {
|
||||||
ul.children().css({position:"relative",left:"",transition:""});
|
ul.children().css({position:"relative",left:"",transition:""});
|
||||||
|
@ -166,13 +166,16 @@ RED.workspaces = (function() {
|
|||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
setWorkspaceOrder(newOrder);
|
setWorkspaceOrder(newOrder);
|
||||||
},
|
},
|
||||||
minimumActiveTabWidth: 150
|
minimumActiveTabWidth: 150,
|
||||||
|
scrollable: true,
|
||||||
|
addButton: function() {
|
||||||
|
addWorkspace();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
createWorkspaceTabs();
|
createWorkspaceTabs();
|
||||||
$('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()});
|
|
||||||
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
||||||
|
|
||||||
RED.menu.setAction('menu-item-workspace-delete',function() {
|
RED.menu.setAction('menu-item-workspace-delete',function() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2015 IBM Corp.
|
* Copyright 2015, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,20 +14,34 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
ul.red-ui-tabs {
|
.red-ui-tabs {
|
||||||
|
position: relative;
|
||||||
|
background: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 35px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.red-ui-tabs-scroll-container {
|
||||||
|
height: 60px;
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: hidden;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& ul {
|
||||||
|
//background: #9999ff;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding:0;
|
padding:0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: block;
|
display: block;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
box-sizing:border-box;
|
box-sizing:border-box;
|
||||||
white-space: nowrap;
|
|
||||||
border-bottom: 1px solid $primary-border-color;
|
border-bottom: 1px solid $primary-border-color;
|
||||||
background: #fff;
|
white-space: nowrap;
|
||||||
@include disable-selection;
|
@include disable-selection;
|
||||||
}
|
|
||||||
|
|
||||||
ul.red-ui-tabs li {
|
li {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-left: 1px solid $primary-border-color;
|
border-left: 1px solid $primary-border-color;
|
||||||
@ -42,19 +56,132 @@ ul.red-ui-tabs li {
|
|||||||
width: 14%;
|
width: 14%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
position: relative;
|
||||||
|
|
||||||
ul.red-ui-tabs li a.red-ui-tab-label {
|
a.red-ui-tab-label {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:focus {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.active) a:hover+a.red-ui-tab-close {
|
||||||
|
background: $tab-background-hover;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
background: $tab-background-active;
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
a.red-ui-tab-close {
|
||||||
|
color: #aaa;
|
||||||
|
background: $tab-background-active;
|
||||||
|
&:hover {
|
||||||
|
background: $workspace-button-background-hover !important;
|
||||||
|
color: $workspace-button-color-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-tab-icon {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:not(.active) a:hover {
|
||||||
|
color: $workspace-button-color-hover;
|
||||||
|
background: $tab-background-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.red-ui-tabs-scrollable {
|
||||||
|
padding-left: 21px;
|
||||||
|
padding-right: 21px;
|
||||||
|
}
|
||||||
|
&.red-ui-tabs-add {
|
||||||
|
padding-right: 35px;
|
||||||
|
}
|
||||||
|
&.red-ui-tabs-add.red-ui-tabs-scrollable {
|
||||||
|
padding-right: 59px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ul.red-ui-tabs li {
|
.red-ui-tab-button {
|
||||||
position: relative;
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 35px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid $primary-border-color;
|
||||||
|
z-index: 3;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@include workspace-button;
|
||||||
|
line-height: 32px;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-right:3px;
|
||||||
|
margin-left:3px;
|
||||||
|
border: 1px solid $primary-border-color;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-ui-tab-scroll {
|
||||||
|
width: 21px;
|
||||||
|
top: 0;
|
||||||
|
a {
|
||||||
|
height: 35px;
|
||||||
|
width: 21px;
|
||||||
|
display: block;
|
||||||
|
color: $link-color;
|
||||||
|
font-size: 22px;
|
||||||
|
text-align: center;
|
||||||
|
margin:0;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-tab-scroll-left {
|
||||||
|
left:0;
|
||||||
|
a {
|
||||||
|
border-right: 1px solid $primary-border-color;
|
||||||
|
// box-shadow: 8px 0px 5px -2px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-tab-scroll-right {
|
||||||
|
right: 0px;
|
||||||
|
a {
|
||||||
|
border-left: 1px solid $primary-border-color;
|
||||||
|
// box-shadow: -8px 0px 5px -2px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.red-ui-tabs.red-ui-tabs-add .red-ui-tab-scroll-right {
|
||||||
|
right: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-tab-icon {
|
||||||
|
margin-left: -8px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-top: -2px;
|
||||||
|
opacity: 0.1;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
.red-ui-tabs-badges {
|
.red-ui-tabs-badges {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:2px;
|
top:2px;
|
||||||
@ -96,51 +223,3 @@ ul.red-ui-tabs li {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ul.red-ui-tabs li:not(.active) a:hover+a.red-ui-tab-close {
|
|
||||||
background: $tab-background-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.red-ui-tabs li.active a.red-ui-tab-close {
|
|
||||||
color: #aaa;
|
|
||||||
background: $tab-background-active;
|
|
||||||
&:hover {
|
|
||||||
background: $workspace-button-background-hover !important;
|
|
||||||
color: $workspace-button-color-hover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.red-ui-tabs li a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.red-ui-tabs li:not(.active) a:hover {
|
|
||||||
color: $workspace-button-color-hover;
|
|
||||||
background: $tab-background-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.red-ui-tabs li a:focus {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.red-ui-tabs li.active {
|
|
||||||
background: $tab-background-active;
|
|
||||||
font-weight: bold;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
ul.red-ui-tabs li.active a {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.red-ui-tab-icon {
|
|
||||||
margin-left: -8px;
|
|
||||||
margin-right: 3px;
|
|
||||||
margin-top: -2px;
|
|
||||||
opacity: 0.1;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
ul.red-ui-tabs li.active .red-ui-tab-icon {
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
|
@ -48,33 +48,6 @@
|
|||||||
@include component-footer-button;
|
@include component-footer-button;
|
||||||
}
|
}
|
||||||
|
|
||||||
#workspace-tabs {
|
|
||||||
margin-right: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#workspace-add-tab {
|
|
||||||
position: absolute;
|
|
||||||
box-sizing: border-box;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 35px;
|
|
||||||
width: 35px;
|
|
||||||
background: #fff;
|
|
||||||
border-bottom: 1px solid $primary-border-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btn-workspace-add-tab {
|
|
||||||
@include workspace-button;
|
|
||||||
line-height: 32px;
|
|
||||||
height: 32px;
|
|
||||||
width: 32px;
|
|
||||||
margin-top: 3px;
|
|
||||||
margin-right:3px;
|
|
||||||
border: 1px solid $primary-border-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspace-footer {
|
#workspace-footer {
|
||||||
@include component-footer;
|
@include component-footer;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
<div id="main-container" class="sidebar-closed hide">
|
<div id="main-container" class="sidebar-closed hide">
|
||||||
<div id="workspace">
|
<div id="workspace">
|
||||||
<ul id="workspace-tabs"></ul>
|
<ul id="workspace-tabs"></ul>
|
||||||
<div id="workspace-add-tab"><a id="btn-workspace-add-tab" href="#"><i class="fa fa-plus"></i></a></div>
|
|
||||||
<div id="chart" tabindex="1"></div>
|
<div id="chart" tabindex="1"></div>
|
||||||
<div id="workspace-toolbar"></div>
|
<div id="workspace-toolbar"></div>
|
||||||
<div id="workspace-footer">
|
<div id="workspace-footer">
|
||||||
|
Loading…
Reference in New Issue
Block a user