Eugene Pankov 3 years ago
parent
commit
4943e2cd5e

+ 1 - 0
tabby-core/package.json

@@ -18,6 +18,7 @@
   "license": "MIT",
   "devDependencies": {
     "bootstrap": "^5.3.0-alpha.1",
+    "color": "^4.2.3",
     "deepmerge": "^4.1.1",
     "fuzzy-search": "^3.2.1",
     "js-yaml": "^4.0.0",

+ 6 - 5
tabby-core/src/components/selfPositioning.component.ts

@@ -1,11 +1,12 @@
-import { HostBinding, ElementRef } from '@angular/core'
+import { HostBinding, ElementRef, Component } from '@angular/core'
 import { BaseComponent } from './base.component'
 
+@Component({})
 export abstract class SelfPositioningComponent extends BaseComponent {
-    @HostBinding('style.left') cssLeft: string
-    @HostBinding('style.top') cssTop: string
-    @HostBinding('style.width') cssWidth: string | null
-    @HostBinding('style.height') cssHeight: string | null
+    @HostBinding('style.left') cssLeft = ''
+    @HostBinding('style.top') cssTop = ''
+    @HostBinding('style.width') cssWidth: string | null = null
+    @HostBinding('style.height') cssHeight: string | null = null
 
     constructor (protected element: ElementRef) { super() }
 

+ 32 - 10
tabby-core/src/services/themes.service.ts

@@ -1,5 +1,6 @@
 import { Inject, Injectable } from '@angular/core'
 import { Subject, Observable } from 'rxjs'
+import * as Color from 'color'
 import { ConfigService } from '../services/config.service'
 import { Theme } from '../api/theme'
 
@@ -28,24 +29,45 @@ export class ThemesService {
 
     private applyThemeVariables () {
         const theme = this.config.store.terminal.colorScheme
-        document.documentElement.style.setProperty('--bs-body-bg', this.config.store?.appearance.vibrancy ? 'rgba(255, 255, 255,.4)' : theme.background)
+        const background = this.config.store?.appearance.vibrancy ? 'rgba(255, 255, 255,.4)' : theme.background
+        const backgroundDark = this.config.store?.appearance.vibrancy ? 'rgba(255, 255, 255,.5)' : Color(theme.background).darken(0.25).string()
+        const accentIndex = 4
+        document.documentElement.style.setProperty('--bs-body-bg', background)
         document.documentElement.style.setProperty('--bs-body-color', theme.foreground)
         document.documentElement.style.setProperty('--bs-black', theme.colors[0])
-        document.documentElement.style.setProperty('--bs-blue', theme.colors[1])
+        document.documentElement.style.setProperty('--bs-red', theme.colors[1])
         document.documentElement.style.setProperty('--bs-green', theme.colors[2])
-        document.documentElement.style.setProperty('--bs-cyan', theme.colors[3])
-        document.documentElement.style.setProperty('--bs-red', theme.colors[4])
+        document.documentElement.style.setProperty('--bs-yellow', theme.colors[3])
+        document.documentElement.style.setProperty('--bs-blue', theme.colors[4])
         document.documentElement.style.setProperty('--bs-purple', theme.colors[5])
-        document.documentElement.style.setProperty('--bs-yellow', theme.colors[6])
+        document.documentElement.style.setProperty('--bs-cyan', theme.colors[6])
         document.documentElement.style.setProperty('--bs-gray', theme.colors[7])
         document.documentElement.style.setProperty('--bs-gray-dark', theme.colors[8])
-        // document.documentElement.style.setProperty('--bs-blue', theme.colors[9])
+        // document.documentElement.style.setProperty('--bs-red', theme.colors[9])
         // document.documentElement.style.setProperty('--bs-green', theme.colors[10])
-        // document.documentElement.style.setProperty('--bs-cyan', theme.colors[11])
-        // document.documentElement.style.setProperty('--bs-red', theme.colors[12])
+        // document.documentElement.style.setProperty('--bs-yellow', theme.colors[11])
+        // document.documentElement.style.setProperty('--bs-blue', theme.colors[12])
         // document.documentElement.style.setProperty('--bs-purple', theme.colors[13])
-        // document.documentElement.style.setProperty('--bs-yellow', theme.colors[14])
-        document.documentElement.style.setProperty('--bs-white', theme.colors[15])
+        // document.documentElement.style.setProperty('--bs-cyan', theme.colors[14])
+
+        document.documentElement.style.setProperty('--theme-fg-light', Color(theme.foreground).lighten(0.25).string())
+        document.documentElement.style.setProperty('--theme-bg-dark', backgroundDark)
+        document.documentElement.style.setProperty('--theme-bg-darker', Color(backgroundDark).darken(0.25).string())
+
+        for (const [color, index] of Object.entries({
+            primary: accentIndex,
+            secondary: 8,
+            warning: 3,
+            danger: 1,
+            success: 2,
+            dark: 0,
+            light: 15,
+        })) {
+            document.documentElement.style.setProperty(`--bs-${color}`, theme.colors[index])
+            document.documentElement.style.setProperty(`--theme-${color}`, theme.colors[index])
+            document.documentElement.style.setProperty(`--theme-${color}-dark`, Color(theme.colors[index]).darken(0.25).string())
+            document.documentElement.style.setProperty(`--theme-${color}-darker`, Color(theme.colors[index]).darken(0.5).string())
+        }
     }
 
     findTheme (name: string): Theme|null {

+ 207 - 183
tabby-core/src/theme.new.scss

@@ -6,7 +6,7 @@ app-root {
 
     &> .content {
         .tab-bar {
-            background: var(--bs-gray-dark);
+            background: var(--theme-bg-dark);
 
             .btn-tab-bar {
                 background: transparent;
@@ -158,18 +158,9 @@ $tab-border-radius: 5px;
 // $dropdown-link-disabled-color:   #333;
 // $dropdown-header-color:          #333;
 
-// $list-group-color: $body-color;
-// $list-group-bg: rgba($black,.05);
-// $list-group-border-color:  rgba($black,.1);
-// $list-group-hover-bg: rgba($black,.1);
-// $list-group-link-active-bg: rgba($black,.2);
-
-// $list-group-action-color: $body-color;
 // $list-group-action-bg: rgba($black,.05);
 // $list-group-action-active-bg: $list-group-link-active-bg;
 
-// $list-group-border-radius: 0;
-
 // $pre-bg: $dropdown-bg;
 // $pre-color: $dropdown-link-color;
 
@@ -180,6 +171,24 @@ $tab-border-radius: 5px;
 @import "./theme.vendor.scss";
 
 
+.list-group {
+    --bs-list-group-bg: var(--theme-bg-dark);
+    --bs-list-group-border-color: var(--theme-bg-darker);
+    --bs-list-group-border-width: 0;
+    // --bs-list-group-item-padding-x: 1rem;
+    // --bs-list-group-item-padding-y: 0.5rem;
+    --bs-list-group-action-color: var(--bs-body-color);
+    --bs-list-group-action-hover-color: var(--theme-fg);
+    --bs-list-group-action-hover-bg: var(--theme-bg-darker);
+
+    --bs-list-group-action-active-color: var(--theme-fg);
+    --bs-list-group-action-active-bg: var(--theme-bg-darker);
+    --bs-list-group-disabled-color: var(--bs-secondary-color);
+    --bs-list-group-disabled-bg: var(--bs-body-bg);
+    // --bs-list-group-active-color: #fff;
+    // --bs-list-group-active-bg: #0d6efd;
+    // --bs-list-group-active-border-color: #0d6efd;
+}
 
 .nav {
     // scss-docs-start nav-css-vars
@@ -188,7 +197,7 @@ $tab-border-radius: 5px;
     // @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
     // --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
     --#{$prefix}nav-link-color: var(--bs-body-color);
-    --#{$prefix}nav-link-hover-color: var(--bs-white);
+    --#{$prefix}nav-link-hover-color: var(--theme-fg-light);
     --#{$prefix}nav-link-disabled-color: var(--bs-gray);
     // scss-docs-end nav-css-vars
 }
@@ -209,8 +218,8 @@ $tab-border-radius: 5px;
 .nav-pills {
     // scss-docs-start nav-pills-css-vars
     --#{$prefix}nav-pills-border-radius: #{$nav-pills-border-radius};
-    --#{$prefix}nav-pills-link-active-color: #{$nav-pills-link-active-color};
-    --#{$prefix}nav-pills-link-active-bg: #{$nav-pills-link-active-bg};
+    --#{$prefix}nav-pills-link-active-color: var(--theme-light);
+    --#{$prefix}nav-pills-link-active-bg: var(--bs-primary);
     // scss-docs-end nav-pills-css-vars
 }
 
@@ -252,147 +261,170 @@ $tab-border-radius: 5px;
 }
 
 
-// tab-body {
-//     background: $content-bg;
+tab-body {
+    terminal-toolbar {
+        background: var(--bs-body-bg);
 
-//     terminal-toolbar .btn, .toolbar-pin-button {
-//         font-weight: bold;
-//     }
-// }
+        .btn, .toolbar-pin-button {
+            font-weight: bold;
+        }
+    }
+}
 
-// multi-hotkey-input {
-//     .item {
-//         background: $body-bg2;
-//         border: 1px solid $blue;
-//         border-radius: 3px;
-//         margin-right: 5px;
+@each $color, $value in $theme-colors {
+    .btn-#{$color} {
+        // 6c757d
+        --bs-btn-bg: var(--theme-#{$color});
+        --bs-btn-border-color: var(--theme-#{$color});
+        --bs-btn-disabled-bg: var(--theme-#{$color});
+        --bs-btn-disabled-border-color: var(--theme-#{$color});
 
-//         .body {
-//             padding: 3px 0 2px;
+        --bs-btn-hover-border-color: var(--theme-#{$color}-dark);
+        --bs-btn-hover-bg: var(--theme-#{$color}-dark);
 
-//             .stroke {
-//                 padding: 0 6px;
-//                 border-right: 1px solid $content-bg;
-//             }
-//         }
+        --bs-btn-active-border-color: var(--theme-#{$color}-darker);
+        --bs-btn-active-bg: var(--theme-#{$color}-darker);
 
-//         .remove {
-//             padding: 3px 8px 2px;
-//         }
-//     }
 
-//     .item:has(.duplicate) {
-//         background-color: map-get($theme-colors, 'danger');
-//         border: 1px solid map-get($theme-colors, 'danger');
-//     }
+        --bs-btn-color: #fff;
+        --bs-btn-hover-color: #fff;
+        --bs-btn-focus-shadow-rgb: 130, 138, 145;
+        --bs-btn-active-color: #fff;
+        --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+        --bs-btn-disabled-color: #fff;
+    }
+}
 
-//     .add {
-//         color: #777;
-//         padding: 4px 10px 0;
-//     }
 
-//     .add, .item .body, .item .remove {
-//         &:hover { background: darken($body-bg2, 5%); }
-//         &:active { background: darken($body-bg2, 15%); }
-//     }
+multi-hotkey-input {
+    .item {
+        background: var(--theme-bg-dark);
+        border: 1px solid var(--bs-primary);
+        border-radius: 3px;
+        margin-right: 5px;
 
-//     .add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
-//         &:hover { background: darken(map-get($theme-colors, 'danger'), 5%); }
-//         &:active { background: darken(map-get($theme-colors, 'danger'), 15%); }
-//     }
-// }
+        .body {
+            padding: 3px 0 2px;
 
-// hotkey-input-modal {
-//     .input {
-//         background: $input-bg;
-//         padding: 10px;
-//         font-size: 24px;
-//         line-height: 27px;
-//         height: 55px;
-
-//         .stroke {
-//             background: $body-bg2;
-//             border: 1px solid $blue;
-//             border-radius: 3px;
-//             margin-right: 10px;
-//             padding: 3px 10px;
-//         }
-//     }
+            .stroke {
+                padding: 0 6px;
+                border-right: 1px solid var(--bs-body-bg);
+            }
+        }
 
-//     .timeout {
-//         background: $input-bg;
+        .remove {
+            padding: 3px 8px 2px;
+        }
+    }
 
-//         div {
-//             background: $blue;
-//         }
-//     }
-// }
+    .item:has(.duplicate) {
+        background-color: var(--bs-danger);
+        border: 1px solid var(--bs-danger);
+    }
 
-// .mb-3 label {
-//     margin-bottom: 2px;
-// }
+    .add {
+        color: #777;
+        padding: 4px 10px 0;
+    }
 
-// .btn-check:checked + label {
-//     background: $blue;
-// }
+    .add, .item .body, .item .remove {
+        &:hover { background: var(--theme-bg-dark); }
+        &:active { background: var(--theme-bg-darker); }
+    }
 
-// .btn {
-//     i + * {
-//         margin-left: 5px;
-//     }
+    .add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
+        &:hover { background: var(--theme-danger-dark); }
+        &:active { background: var(--theme-danger-darker); }
+    }
+}
 
-//     &.btn-lg i + * {
-//         margin-left: 10px;
-//     }
-// }
+hotkey-input-modal {
+    .input {
+        // background: $input-bg;
+        padding: 10px;
+        font-size: 24px;
+        line-height: 27px;
+        height: 55px;
+
+        .stroke {
+            background: var(--theme-bg-dark);
+            border: 1px solid var(--bs-primary);
+            border-radius: 3px;
+            margin-right: 10px;
+            padding: 3px 10px;
+        }
+    }
 
-// .input-group-addon + .form-control {
-//     border-left: none;
-// }
+    .timeout {
+        background: $input-bg;
 
-// .input-group > select.form-control {
-//     flex-direction: row;
-// }
+        div {
+            background: $blue;
+        }
+    }
+}
 
-// .list-group-item {
-//     // transition: 0.0625s background ease;
+.mb-3 label {
+    margin-bottom: 2px;
+}
 
-//     i + * {
-//         margin-left: 10px;
-//     }
-// }
+.btn {
+    i + * {
+        margin-left: 5px;
+    }
 
-// .list-group.list-group-flush .list-group-item {
-//     background: transparent;
-//     border: none;
+    &.btn-lg i + * {
+        margin-left: 10px;
+    }
+}
 
-//     &:not(:last-child) {
-//         border-bottom: none;
-//     }
+.input-group-addon + .form-control {
+    border-left: none;
+}
 
-//     &.list-group-item-action {
-//         &:hover, &.active {
-//             background: $list-group-hover-bg;
-//         }
-//     }
-// }
+.input-group > select.form-control {
+    flex-direction: row;
+}
 
-// .list-group-light {
-//     .list-group-item {
-//         border: none !important;
-//         outline: none !important;
-//         background: transparent;
-//         border-radius: $border-radius;
-//         margin: 0 !important;
-
-//         &.list-group-item-action {
-//             &:hover, &.active {
-//                 background: $component-active-bg;
-//                 color: $component-active-color;
-//             }
-//         }
-//     }
-// }
+.list-group-item {
+    // transition: 0.0625s background ease;
+
+    i + * {
+        margin-left: 10px;
+    }
+}
+
+.list-group.list-group-flush .list-group-item {
+    background: transparent;
+    border: none;
+
+    &:not(:last-child) {
+        border-bottom: none;
+    }
+
+    &.list-group-item-action {
+        &:hover, &.active {
+            // background: $list-group-hover-bg;
+        }
+    }
+}
+
+.list-group-light {
+    .list-group-item {
+        border: none !important;
+        outline: none !important;
+        background: transparent;
+        border-radius: $border-radius;
+        margin: 0 !important;
+
+        &.list-group-item-action {
+            &:hover, &.active {
+                background: var(--bs-primary);
+                color: var(--bs-body-color);
+            }
+        }
+    }
+}
 
 // checkbox i.on {
 //     color: $blue;
@@ -407,58 +439,45 @@ $tab-border-radius: 5px;
 //     }
 // }
 
-// .list-group-item svg {
-//     fill: white;
-//     fill-opacity: 0.75;
-// }
-
-// *::-webkit-scrollbar {
-//     background: rgba(0, 0, 0, .125);
-//     width: 10px;
-//     margin: 5px;
-// }
+.list-group-item svg {
+    fill: var(--bs-body-color);
+    fill-opacity: 0.75;
+}
 
-// *::-webkit-scrollbar-thumb {
-//     background: rgba(255, 255, 255, .25);
-// }
+*::-webkit-scrollbar {
+    background: rgba(0, 0, 0, .125);
+    width: 10px;
+    margin: 5px;
+}
 
-// *::-webkit-scrollbar-corner,
-// *::-webkit-resizer {
-//     opacity: 0;
-// }
+*::-webkit-scrollbar-thumb {
+    background: rgba(255, 255, 255, .25);
+}
 
-// search-panel {
-//     background: #131d27 !important;
+*::-webkit-scrollbar-corner,
+*::-webkit-resizer {
+    opacity: 0;
+}
 
-//     input {
-//         border-radius: 0 !important;
-//     }
-// }
+search-panel {
+    background: var(--theme-bg-dark) !important;
 
+    input {
+        border-radius: 0 !important;
+    }
+}
 
-// .btn {
-//     cursor: pointer;
-//     justify-content: flex-start;
-//     overflow: hidden;
 
-//     &.disabled,
-//     &:disabled {
-//         cursor: not-allowed;
-//     }
-// }
+.btn {
+    cursor: pointer;
+    justify-content: flex-start;
+    overflow: hidden;
 
-// .btn-warning:not(:disabled):not(.disabled) {
-//     &.active, &:active {
-//         color: $gray-900;
-//     }
-// }
-
-// .btn-secondary:not(:disabled):not(.disabled) {
-//     &.active, &:active {
-//         background: #191e23;
-//         align-items: center;
-//     }
-// }
+    &.disabled,
+    &:disabled {
+        cursor: not-allowed;
+    }
+}
 
 // .btn-link {
 //     text-decoration: none;
@@ -486,14 +505,19 @@ $tab-border-radius: 5px;
 //     box-shadow: $dropdown-box-shadow;
 // }
 
-// ngx-colors-panel .opened {
-//     background: $body-bg !important;
+ngx-colors-panel .opened {
+    background: var(--bs-body-bg) !important;
 
-//     button {
-//         color: $body-color !important;
-//     }
+    button {
+        color: var(--bs-body-color) !important;
+    }
 
-//     .button svg {
-//         fill: white;
-//     }
-// }
+    .button svg {
+        fill: white;
+    }
+}
+
+.text-muted {
+    color: var(--bs-body-color) !important;
+    opacity: .5;
+}

+ 40 - 0
tabby-core/yarn.lock

@@ -39,6 +39,34 @@ buffer@^6.0.3:
     base64-js "^1.3.1"
     ieee754 "^1.2.1"
 
+color-convert@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+  integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+  dependencies:
+    color-name "~1.1.4"
+
+color-name@^1.0.0, color-name@~1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+  integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+color-string@^1.9.0:
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
+  integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
+  dependencies:
+    color-name "^1.0.0"
+    simple-swizzle "^0.2.2"
+
+color@^4.2.3:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
+  integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
+  dependencies:
+    color-convert "^2.0.1"
+    color-string "^1.9.0"
+
 debug@4:
   version "4.3.1"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
@@ -79,6 +107,11 @@ ieee754@^1.2.1:
   resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
   integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
 
+is-arrayish@^0.3.1:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
+  integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
+
 js-yaml@^4.0.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
@@ -151,6 +184,13 @@ [email protected]:
     events "^3.3.0"
     process "^0.11.10"
 
+simple-swizzle@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
+  integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
+  dependencies:
+    is-arrayish "^0.3.1"
+
 tslib@^1.10.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"

+ 6 - 7
tabby-terminal/src/components/terminalToolbar.component.scss

@@ -1,8 +1,13 @@
 :host {
-    background: #000000bf;
     padding: 5px 15px 5px 15px;
     display: flex;
     z-index: 3;
+
+    ::ng-deep .btn {
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+    }
 }
 
 .content {
@@ -16,9 +21,3 @@
     cursor: move;
     opacity: .3;
 }
-
-::ng-deep .btn {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}