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() {
|
||||
|
||||
|
||||
function createTabs(options) {
|
||||
var tabs = {};
|
||||
var currentTabWidth;
|
||||
var currentActiveTabWidth = 0;
|
||||
|
||||
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().addClass("red-ui-tab");
|
||||
|
||||
@ -34,6 +77,23 @@ RED.tabs = (function() {
|
||||
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() {
|
||||
if (options.ondblclick) {
|
||||
options.ondblclick(tabs[$(this).attr('href').slice(1)]);
|
||||
@ -49,6 +109,14 @@ RED.tabs = (function() {
|
||||
ul.children().removeClass("active");
|
||||
ul.children().css({"transition": "width 100ms"});
|
||||
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) {
|
||||
options.onchange(tabs[link.attr('href').slice(1)]);
|
||||
}
|
||||
@ -61,23 +129,29 @@ RED.tabs = (function() {
|
||||
|
||||
function updateTabWidths() {
|
||||
var tabs = ul.find("li.red-ui-tab");
|
||||
var width = ul.width();
|
||||
var width = wrapper.width();
|
||||
var tabCount = tabs.size();
|
||||
var tabWidth = (width-12-(tabCount*6))/tabCount;
|
||||
currentTabWidth = 100*tabWidth/width;
|
||||
currentTabWidth = (100*tabWidth/width)+"%";
|
||||
currentActiveTabWidth = currentTabWidth+"%";
|
||||
|
||||
if (options.hasOwnProperty("minimumActiveTabWidth")) {
|
||||
if (options.scrollable) {
|
||||
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) {
|
||||
tabCount -= 1;
|
||||
tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount;
|
||||
currentTabWidth = 100*tabWidth/width;
|
||||
currentTabWidth = (100*tabWidth/width)+"%";
|
||||
currentActiveTabWidth = options.minimumActiveTabWidth+"px";
|
||||
} else {
|
||||
currentActiveTabWidth = 0;
|
||||
}
|
||||
}
|
||||
tabs.css({width:currentTabWidth+"%"});
|
||||
tabs.css({width:currentTabWidth});
|
||||
if (tabWidth < 50) {
|
||||
ul.find(".red-ui-tab-close").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);
|
||||
setTimeout(function() {
|
||||
updateTabWidths();
|
||||
},0);
|
||||
|
||||
|
||||
function removeTab(id) {
|
||||
@ -210,8 +286,6 @@ RED.tabs = (function() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(ui.position.left,ui.offset.left);
|
||||
},
|
||||
stop: function(event,ui) {
|
||||
ul.children().css({position:"relative",left:"",transition:""});
|
||||
|
@ -166,13 +166,16 @@ RED.workspaces = (function() {
|
||||
RED.nodes.dirty(true);
|
||||
setWorkspaceOrder(newOrder);
|
||||
},
|
||||
minimumActiveTabWidth: 150
|
||||
minimumActiveTabWidth: 150,
|
||||
scrollable: true,
|
||||
addButton: function() {
|
||||
addWorkspace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
createWorkspaceTabs();
|
||||
$('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()});
|
||||
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
||||
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,20 +14,34 @@
|
||||
* 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;
|
||||
padding:0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
height: 35px;
|
||||
box-sizing:border-box;
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
background: #fff;
|
||||
white-space: nowrap;
|
||||
@include disable-selection;
|
||||
}
|
||||
|
||||
ul.red-ui-tabs li {
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
border-left: 1px solid $primary-border-color;
|
||||
@ -42,9 +56,9 @@ ul.red-ui-tabs li {
|
||||
width: 14%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
position: relative;
|
||||
|
||||
ul.red-ui-tabs li a.red-ui-tab-label {
|
||||
a.red-ui-tab-label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
padding-left: 12px;
|
||||
@ -52,9 +66,122 @@ ul.red-ui-tabs li a.red-ui-tab-label {
|
||||
height: 100%;
|
||||
color: #666;
|
||||
}
|
||||
ul.red-ui-tabs li {
|
||||
position: relative;
|
||||
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;
|
||||
}
|
||||
}
|
||||
.red-ui-tab-button {
|
||||
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 {
|
||||
position: absolute;
|
||||
top:2px;
|
||||
@ -96,51 +223,3 @@ ul.red-ui-tabs li {
|
||||
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;
|
||||
}
|
||||
|
||||
#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 {
|
||||
@include component-footer;
|
||||
}
|
||||
|
@ -45,7 +45,6 @@
|
||||
<div id="main-container" class="sidebar-closed hide">
|
||||
<div id="workspace">
|
||||
<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="workspace-toolbar"></div>
|
||||
<div id="workspace-footer">
|
||||
|
Loading…
Reference in New Issue
Block a user