diff --git a/tabby-core/package.json b/tabby-core/package.json index 4b9dc437..78fb90b8 100644 --- a/tabby-core/package.json +++ b/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", diff --git a/tabby-core/src/components/selfPositioning.component.ts b/tabby-core/src/components/selfPositioning.component.ts index f2d36d26..63130166 100644 --- a/tabby-core/src/components/selfPositioning.component.ts +++ b/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() } diff --git a/tabby-core/src/services/themes.service.ts b/tabby-core/src/services/themes.service.ts index 31f9d6cb..abf59ec2 100644 --- a/tabby-core/src/services/themes.service.ts +++ b/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 { diff --git a/tabby-core/src/theme.new.scss b/tabby-core/src/theme.new.scss index d1840d23..fdce8153 100644 --- a/tabby-core/src/theme.new.scss +++ b/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 { + padding: 0 6px; + border-right: 1px solid var(--bs-body-bg); + } + } -// .stroke { -// background: $body-bg2; -// border: 1px solid $blue; -// border-radius: 3px; -// margin-right: 10px; -// padding: 3px 10px; -// } -// } + .remove { + padding: 3px 8px 2px; + } + } -// .timeout { -// background: $input-bg; + .item:has(.duplicate) { + background-color: var(--bs-danger); + border: 1px solid var(--bs-danger); + } -// div { -// background: $blue; -// } -// } -// } + .add { + color: #777; + padding: 4px 10px 0; + } -// .mb-3 label { -// margin-bottom: 2px; -// } + .add, .item .body, .item .remove { + &:hover { background: var(--theme-bg-dark); } + &:active { background: var(--theme-bg-darker); } + } -// .btn-check:checked + label { -// background: $blue; -// } + .add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove { + &:hover { background: var(--theme-danger-dark); } + &:active { background: var(--theme-danger-darker); } + } +} -// .btn { -// i + * { -// margin-left: 5px; -// } +hotkey-input-modal { + .input { + // background: $input-bg; + padding: 10px; + font-size: 24px; + line-height: 27px; + height: 55px; -// &.btn-lg i + * { -// margin-left: 10px; -// } -// } + .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 { + // transition: 0.0625s background ease; -// &.list-group-item-action { -// &:hover, &.active { -// background: $component-active-bg; -// color: $component-active-color; -// } -// } -// } -// } + 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; -// } +.list-group-item svg { + fill: var(--bs-body-color); + fill-opacity: 0.75; +} -// *::-webkit-scrollbar { -// background: rgba(0, 0, 0, .125); -// width: 10px; -// margin: 5px; -// } +*::-webkit-scrollbar { + background: rgba(0, 0, 0, .125); + width: 10px; + margin: 5px; +} -// *::-webkit-scrollbar-thumb { -// background: rgba(255, 255, 255, .25); -// } +*::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, .25); +} -// *::-webkit-scrollbar-corner, -// *::-webkit-resizer { -// opacity: 0; -// } +*::-webkit-scrollbar-corner, +*::-webkit-resizer { + opacity: 0; +} -// search-panel { -// background: #131d27 !important; +search-panel { + background: var(--theme-bg-dark) !important; -// input { -// border-radius: 0 !important; -// } -// } + input { + border-radius: 0 !important; + } +} -// .btn { -// cursor: pointer; -// justify-content: flex-start; -// overflow: hidden; +.btn { + cursor: pointer; + justify-content: flex-start; + overflow: hidden; -// &.disabled, -// &:disabled { -// cursor: not-allowed; -// } -// } - -// .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; +} diff --git a/tabby-core/yarn.lock b/tabby-core/yarn.lock index 16e630cd..88ca5086 100644 --- a/tabby-core/yarn.lock +++ b/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 @@ readable-stream@4.2.0: 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" diff --git a/tabby-terminal/src/components/terminalToolbar.component.scss b/tabby-terminal/src/components/terminalToolbar.component.scss index 65b352f3..79bca1ce 100644 --- a/tabby-terminal/src/components/terminalToolbar.component.scss +++ b/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; -}