add new tab button, WIP

This commit is contained in:
zadam 2019-05-12 10:59:53 +02:00
parent c39c1baa4d
commit 637547a3fa
3 changed files with 62 additions and 39 deletions

View File

@ -42,8 +42,6 @@ class TabContext {
this.tab = this.tabRow.addTab({ this.tab = this.tabRow.addTab({
title: '', // will be set later title: '', // will be set later
id: this.tabId id: this.tabId
}, {
background: true
}); });
this.$tabContent = $(".note-tab-content-template").clone(); this.$tabContent = $(".note-tab-content-template").clone();

View File

@ -11,25 +11,12 @@ const Draggabilly = window.Draggabilly;
const TAB_CONTENT_MIN_WIDTH = 24; const TAB_CONTENT_MIN_WIDTH = 24;
const TAB_CONTENT_MAX_WIDTH = 240; const TAB_CONTENT_MAX_WIDTH = 240;
const NEW_TAB_WIDTH = 32;
const TAB_SIZE_SMALL = 84; const TAB_SIZE_SMALL = 84;
const TAB_SIZE_SMALLER = 60; const TAB_SIZE_SMALLER = 60;
const TAB_SIZE_MINI = 48; const TAB_SIZE_MINI = 48;
const closest = (value, array) => {
let closest = Infinity;
let closestIndex = -1;
array.forEach((v, i) => {
if (Math.abs(value - v) < closest) {
closest = Math.abs(value - v);
closestIndex = i
}
});
return closestIndex;
};
const tabTemplate = ` const tabTemplate = `
<div class="note-tab"> <div class="note-tab">
<div class="note-tab-wrapper"> <div class="note-tab-wrapper">
@ -39,6 +26,8 @@ const tabTemplate = `
</div> </div>
</div>`; </div>`;
const newTabButtonTemplate = `<div class="note-new-tab" title="Add new tab">+</div>`;
const defaultTapProperties = { const defaultTapProperties = {
title: 'New tab' title: 'New tab'
}; };
@ -62,6 +51,7 @@ class TabRow {
this.setupEvents(); this.setupEvents();
this.layoutTabs(); this.layoutTabs();
this.setupDraggabilly(); this.setupDraggabilly();
this.setupNewButton();
this.setVisibility(); this.setVisibility();
} }
@ -104,7 +94,7 @@ class TabRow {
get tabContentWidths() { get tabContentWidths() {
const numberOfTabs = this.tabEls.length; const numberOfTabs = this.tabEls.length;
const tabsContentWidth = this.tabContentEl.clientWidth; const tabsContentWidth = this.tabContentEl.clientWidth - NEW_TAB_WIDTH;
const targetWidth = tabsContentWidth / numberOfTabs; const targetWidth = tabsContentWidth / numberOfTabs;
const clampedTargetWidth = Math.max(TAB_CONTENT_MIN_WIDTH, Math.min(TAB_CONTENT_MAX_WIDTH, targetWidth)); const clampedTargetWidth = Math.max(TAB_CONTENT_MIN_WIDTH, Math.min(TAB_CONTENT_MAX_WIDTH, targetWidth));
const flooredClampedTargetWidth = Math.floor(clampedTargetWidth); const flooredClampedTargetWidth = Math.floor(clampedTargetWidth);
@ -122,27 +112,19 @@ class TabRow {
return widths; return widths;
} }
get tabContentPositions() { getTabPositions() {
const positions = []; const tabPositions = [];
const tabContentWidths = this.tabContentWidths; const tabContentWidths = this.tabContentWidths;
let position = 0; let position = 0;
tabContentWidths.forEach(width => { tabContentWidths.forEach(width => {
positions.push(position); tabPositions.push(position);
position += width; position += width;
}); });
return positions; const newTabPosition = position;
}
get tabPositions() { return {tabPositions, newTabPosition};
const positions = [];
this.tabContentPositions.forEach((contentPosition) => {
positions.push(contentPosition);
});
return positions;
} }
layoutTabs() { layoutTabs() {
@ -162,7 +144,10 @@ class TabRow {
}); });
let styleHTML = ''; let styleHTML = '';
this.tabPositions.forEach((position, i) => {
const {tabPositions, newTabPosition} = this.getTabPositions();
tabPositions.forEach((position, i) => {
styleHTML += ` styleHTML += `
.note-tab-row[data-note-tab-row-instance-id="${ this.instanceId }"] .note-tab:nth-child(${ i + 1 }) { .note-tab-row[data-note-tab-row-instance-id="${ this.instanceId }"] .note-tab:nth-child(${ i + 1 }) {
transform: translate3d(${ position }px, 0, 0) transform: translate3d(${ position }px, 0, 0)
@ -170,25 +155,24 @@ class TabRow {
` `
}); });
styleHTML += `.note-new-tab { transform: translate3d(${ newTabPosition }px, 0, 0) }`;
this.styleEl.innerHTML = styleHTML; this.styleEl.innerHTML = styleHTML;
} }
addTab(tabProperties, { animate = true, background = false } = {}) { addTab(tabProperties) {
const div = document.createElement('div'); const div = document.createElement('div');
div.innerHTML = tabTemplate; div.innerHTML = tabTemplate;
const tabEl = div.firstElementChild; const tabEl = div.firstElementChild;
if (animate) { tabEl.classList.add('note-tab-was-just-added');
tabEl.classList.add('note-tab-was-just-added'); setTimeout(() => tabEl.classList.remove('note-tab-was-just-added'), 500);
setTimeout(() => tabEl.classList.remove('note-tab-was-just-added'), 500);
}
tabProperties = Object.assign({}, defaultTapProperties, tabProperties); tabProperties = Object.assign({}, defaultTapProperties, tabProperties);
this.tabContentEl.appendChild(tabEl); this.tabContentEl.appendChild(tabEl);
this.setVisibility(); this.setVisibility();
this.setTabCloseEventListener(tabEl); this.setTabCloseEventListener(tabEl);
this.updateTab(tabEl, tabProperties); this.updateTab(tabEl, tabProperties);
if (!background) this.setCurrentTab(tabEl);
this.cleanUpPreviouslyDraggedTabs(); this.cleanUpPreviouslyDraggedTabs();
this.layoutTabs(); this.layoutTabs();
this.setupDraggabilly(); this.setupDraggabilly();
@ -294,7 +278,7 @@ class TabRow {
setupDraggabilly() { setupDraggabilly() {
const tabEls = this.tabEls; const tabEls = this.tabEls;
const tabPositions = this.tabPositions; const {tabPositions} = this.getTabPositions();
if (this.isDragging) { if (this.isDragging) {
this.isDragging = false; this.isDragging = false;
@ -363,7 +347,7 @@ class TabRow {
const currentIndex = tabEls.indexOf(tabEl); const currentIndex = tabEls.indexOf(tabEl);
const currentTabPositionX = originalTabPositionX + moveVector.x; const currentTabPositionX = originalTabPositionX + moveVector.x;
const destinationIndexTarget = closest(currentTabPositionX, tabPositions); const destinationIndexTarget = this.closest(currentTabPositionX, tabPositions);
const destinationIndex = Math.max(0, Math.min(tabEls.length, destinationIndexTarget)); const destinationIndex = Math.max(0, Math.min(tabEls.length, destinationIndexTarget));
if (currentIndex !== destinationIndex) { if (currentIndex !== destinationIndex) {
@ -382,6 +366,29 @@ class TabRow {
await this.emit('tabReorder', { tabEl, originIndex, destinationIndex }); await this.emit('tabReorder', { tabEl, originIndex, destinationIndex });
this.layoutTabs(); this.layoutTabs();
} }
setupNewButton() {
const div = document.createElement('div');
div.innerHTML = newTabButtonTemplate;
this.newTabEl = div.firstElementChild;
this.tabContentEl.appendChild(this.newTabEl);
this.layoutTabs();
}
closest(value, array) {
let closest = Infinity;
let closestIndex = -1;
array.forEach((v, i) => {
if (Math.abs(value - v) < closest) {
closest = Math.abs(value - v);
closestIndex = i
}
});
return closestIndex;
};
} }
const noteTabRowEl = document.querySelector('.note-tab-row'); const noteTabRowEl = document.querySelector('.note-tab-row');

View File

@ -199,6 +199,24 @@ li.dropdown-submenu:hover > ul.dropdown-menu {
pointer-events: none; pointer-events: none;
} }
.note-new-tab {
position: absolute;
left: 0;
height: 32px;
width: 32px;
border: 0;
margin: 0;
z-index: 1;
text-align: center;
font-size: 24px;
cursor: pointer;
}
.note-new-tab:hover {
background-color: var(--accented-background-color);
border-radius: 5px;
}
.note-tab-row .note-tab[active] { .note-tab-row .note-tab[active] {
z-index: 5; z-index: 5;
} }