From dff6a2470c8bd081163a4ff0951c2c83d98ec600 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Sun, 6 Dec 2020 19:12:15 +0100 Subject: [PATCH] refined vertical tabs --- .../src/components/appRoot.component.pug | 212 ++++++++---------- .../src/components/appRoot.component.scss | 48 ++-- .../src/components/appRoot.component.ts | 4 + .../src/components/settingsTab.component.pug | 13 +- 4 files changed, 140 insertions(+), 137 deletions(-) diff --git a/terminus-core/src/components/appRoot.component.pug b/terminus-core/src/components/appRoot.component.pug index 887dfaf6..7630ade9 100644 --- a/terminus-core/src/components/appRoot.component.pug +++ b/terminus-core/src/components/appRoot.component.pug @@ -3,133 +3,105 @@ title-bar( [class.inset]='hostApp.platform == Platform.macOS' ) -.wrap - .tab-bar.vertical( - *ngIf='config.store.appearance.tabsLocation == "left"' - ) - .inset.background(*ngIf='hostApp.platform == Platform.macOS \ - && config.store.appearance.frame == "thin"') - .tabs.vertical( - dnd-sortable-container, - [sortableData]='app.tabs', - ) - tab-header( - *ngFor='let tab of app.tabs; let idx = index', - dnd-sortable, - [sortableIndex]='idx', - (onDragStart)='onTabDragStart()', - (onDragEnd)='onTabDragEnd()', +.content( + [class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"', + [class.tabs-on-side]='hasVerticalTabs()', +) + .tab-bar + .inset.background(*ngIf='hostApp.platform == Platform.macOS \ + && config.store.appearance.frame == "thin" \ + && (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")') + .tabs( + *ngIf='config.store.appearance.tabsLocation != "bottom"' + dnd-sortable-container, + [sortableData]='app.tabs', + ) + tab-header( + *ngFor='let tab of app.tabs; let idx = index', + dnd-sortable, + [sortableIndex]='idx', + (onDragStart)='onTabDragStart()', + (onDragEnd)='onTabDragEnd()', - [index]='idx', - [tab]='tab', - [active]='tab == app.activeTab', - [hasActivity]='tab.activity$|async', - @animateTab, - (click)='app.selectTab(tab)', - [class.fully-draggable]='hostApp.platform != Platform.macOS', - [class.drag-region]='hostApp.platform == Platform.macOS && !tabsDragging', - [class.vertical]='true', - ) + [index]='idx', + [tab]='tab', + [active]='tab == app.activeTab', + [hasActivity]='tab.activity$|async', + @animateTab, + [@.disabled]='hasVerticalTabs()', + (click)='app.selectTab(tab)', + [class.fully-draggable]='hostApp.platform != Platform.macOS', + [class.drag-region]='hostApp.platform == Platform.macOS && !tabsDragging', + ) + .btn-group.background + .d-flex( + *ngFor='let button of leftToolbarButtons', + ngbDropdown, + (openChange)='generateButtonSubmenu(button)', + ) + button.btn.btn-secondary.btn-tab-bar( + [title]='button.title', + (click)='button.click && button.click()', + [fastHtmlBind]='button.icon', + ngbDropdownToggle, + ) + div(*ngIf='button.submenu', ngbDropdownMenu) + button.dropdown-item.d-flex.align-items-center( + *ngFor='let item of button.submenuItems', + (click)='item.click()', + ngbDropdownItem, + ) + .icon-wrapper( + *ngIf='hasIcons(button.submenuItems)', + [fastHtmlBind]='item.icon' + ) + div([class.ml-3]='hasIcons(button.submenuItems)') {{item.title}} - .content( - [class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"', - [class.with-side-tab]='config.store.appearance.tabsLocation == "left"', - ) - .tab-bar - .inset.background(*ngIf='hostApp.platform == Platform.macOS \ - && config.store.appearance.frame == "thin" \ - && (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")') - .tabs( - *ngIf='config.store.appearance.tabsLocation != "left"' - dnd-sortable-container, - [sortableData]='app.tabs', - ) - tab-header( - *ngFor='let tab of app.tabs; let idx = index', - dnd-sortable, - [sortableIndex]='idx', - (onDragStart)='onTabDragStart()', - (onDragEnd)='onTabDragEnd()', + .drag-space.background([class.persistent]='config.store.appearance.frame == "thin" && hostApp.platform != Platform.macOS') - [index]='idx', - [tab]='tab', - [active]='tab == app.activeTab', - [hasActivity]='tab.activity$|async', - @animateTab, - (click)='app.selectTab(tab)', - [class.fully-draggable]='hostApp.platform != Platform.macOS', - [class.drag-region]='hostApp.platform == Platform.macOS && !tabsDragging', - ) + .btn-group.background + .d-flex( + *ngFor='let button of rightToolbarButtons', + ngbDropdown, + (openChange)='generateButtonSubmenu(button)', + ) + button.btn.btn-secondary.btn-tab-bar( + [title]='button.title', + (click)='button.click && button.click()', + [fastHtmlBind]='button.icon', + ngbDropdownToggle, + ) + div(*ngIf='button.submenu', ngbDropdownMenu) + button.dropdown-item.d-flex.align-items-center( + *ngFor='let item of button.submenuItems', + (click)='item.click()', + ngbDropdownItem, + ) + .icon-wrapper( + *ngIf='hasIcons(button.submenuItems)', + [fastHtmlBind]='item.icon' + ) + div([class.ml-3]='hasIcons(button.submenuItems)') {{item.title}} - .btn-group.background - .d-flex( - *ngFor='let button of leftToolbarButtons', - ngbDropdown, - (openChange)='generateButtonSubmenu(button)', - ) - button.btn.btn-secondary.btn-tab-bar( - [title]='button.title', - (click)='button.click && button.click()', - [fastHtmlBind]='button.icon', - ngbDropdownToggle, - ) - div(*ngIf='button.submenu', ngbDropdownMenu) - button.dropdown-item.d-flex.align-items-center( - *ngFor='let item of button.submenuItems', - (click)='item.click()', - ngbDropdownItem, - ) - .icon-wrapper( - *ngIf='hasIcons(button.submenuItems)', - [fastHtmlBind]='item.icon' - ) - div([class.ml-3]='hasIcons(button.submenuItems)') {{item.title}} + button.btn.btn-secondary.btn-tab-bar.btn-update( + *ngIf='updatesAvailable', + title='Update available - Click to install', + (click)='updateApp()', + [fastHtmlBind]='updateIcon' + ) - .drag-space.background([class.persistent]='config.store.appearance.frame == "thin" && hostApp.platform != Platform.macOS') + window-controls.background( + *ngIf='config.store.appearance.frame == "thin" \ + && (hostApp.platform == Platform.Windows || hostApp.platform == Platform.Linux)', + ) - .btn-group.background - .d-flex( - *ngFor='let button of rightToolbarButtons', - ngbDropdown, - (openChange)='generateButtonSubmenu(button)', - ) - button.btn.btn-secondary.btn-tab-bar( - [title]='button.title', - (click)='button.click && button.click()', - [fastHtmlBind]='button.icon', - ngbDropdownToggle, - ) - div(*ngIf='button.submenu', ngbDropdownMenu) - button.dropdown-item.d-flex.align-items-center( - *ngFor='let item of button.submenuItems', - (click)='item.click()', - ngbDropdownItem, - ) - .icon-wrapper( - *ngIf='hasIcons(button.submenuItems)', - [fastHtmlBind]='item.icon' - ) - div([class.ml-3]='hasIcons(button.submenuItems)') {{item.title}} + start-page(*ngIf='ready && app.tabs.length == 0') - button.btn.btn-secondary.btn-tab-bar.btn-update( - *ngIf='updatesAvailable', - title='Update available - Click to install', - (click)='updateApp()', - [fastHtmlBind]='updateIcon' - ) - - window-controls.background( - *ngIf='config.store.appearance.frame == "thin" \ - && (hostApp.platform == Platform.Windows || hostApp.platform == Platform.Linux)', - ) - - start-page(*ngIf='ready && app.tabs.length == 0') - - tab-body( - *ngFor='let tab of unsortedTabs', - [active]='tab == app.activeTab', - [tab]='tab', - ) + tab-body( + *ngFor='let tab of unsortedTabs', + [active]='tab == app.activeTab', + [tab]='tab', + ) ng-template(ngbModalContainer) diff --git a/terminus-core/src/components/appRoot.component.scss b/terminus-core/src/components/appRoot.component.scss index ddb38bf1..76daa36b 100644 --- a/terminus-core/src/components/appRoot.component.scss +++ b/terminus-core/src/components/appRoot.component.scss @@ -35,26 +35,49 @@ $side-tab-width: 200px; flex-direction: column; } - &.with-side-tab { - width: calc(100% - #{$side-tab-width}); + &.tabs-on-side { + flex-direction: row-reverse; + + &.tabs-on-top { + flex-direction: row; + } } } +.content.tabs-on-side > .tab-bar { + height: 100%; + width: $side-tab-width; + overflow-y: auto; + overflow-x: hidden; + flex-direction: column; + background: rgba(0, 0, 0, 0.25); + + .tabs { + width: $side-tab-width; + flex: none; + flex-direction: column; + + tab-header { + flex: 0 0 $tabs-height; + } + } + + .drag-space { + flex: auto; + } +} + + .tab-bar { flex: none; height: $tabs-height; display: flex; width: 100%; - &.vertical { - height: 100%; - width: $side-tab-width; - overflow-y: auto; - overflow-x: hidden; - } .btn-tab-bar { line-height: $tabs-height + 2px; + height: $tabs-height; cursor: pointer; display: flex; @@ -79,12 +102,6 @@ $side-tab-width: 200px; flex: 0 1 auto; display: flex; min-width: 0; - - &.vertical { - width: $side-tab-width; - flex: auto; - flex-direction: column; - } } &>.drag-space { @@ -100,7 +117,10 @@ $side-tab-width: 200px; & > .inset { width: 85px; + height: $tabs-height; flex: none; + opacity: 0; + -webkit-app-region: drag; } window-controls { diff --git a/terminus-core/src/components/appRoot.component.ts b/terminus-core/src/components/appRoot.component.ts index 0ae1171f..16c06999 100644 --- a/terminus-core/src/components/appRoot.component.ts +++ b/terminus-core/src/components/appRoot.component.ts @@ -184,6 +184,10 @@ export class AppRootComponent { return false } + hasVerticalTabs () { + return this.config.store.appearance.tabsLocation === 'left' || this.config.store.appearance.tabsLocation === 'right' + } + async updateApp () { if ((await this.electron.showMessageBox( this.hostApp.getWindow(), diff --git a/terminus-settings/src/components/settingsTab.component.pug b/terminus-settings/src/components/settingsTab.component.pug index b6369316..7a787471 100644 --- a/terminus-settings/src/components/settingsTab.component.pug +++ b/terminus-settings/src/components/settingsTab.component.pug @@ -43,21 +43,28 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab') ngbButton, [value]='"top"' ) - | On the top + | Top label.btn.btn-secondary(ngbButtonLabel) input( type='radio', ngbButton, [value]='"bottom"' ) - | At the bottom + | Bottom label.btn.btn-secondary(ngbButtonLabel) input( type='radio', ngbButton, [value]='"left"' ) - | At the left + | Left + label.btn.btn-secondary(ngbButtonLabel) + input( + type='radio', + ngbButton, + [value]='"right"' + ) + | Right .form-line .header