瀏覽代碼

ui tweaks

Eugene Pankov 6 年之前
父節點
當前提交
b6c97ffa49

+ 10 - 4
terminus-core/src/components/appRoot.component.pug

@@ -47,8 +47,11 @@ title-bar(
                         (click)='item.click()',
                         ngbDropdownItem,
                     )
-                        .icon-wrapper([innerHTML]='sanitizeIcon(item.icon)')
-                        .ml-3 {{item.title}}
+                        .icon-wrapper(
+                            *ngIf='hasIcons(button.submenuItems)',
+                            [innerHTML]='sanitizeIcon(item.icon)'
+                        )
+                        div([class.ml-3]='hasIcons(button.submenuItems)') {{item.title}}
 
         .drag-space.background([class.persistent]='config.store.appearance.frame == "thin" && hostApp.platform != Platform.macOS')
 
@@ -70,8 +73,11 @@ title-bar(
                         (click)='item.click()',
                         ngbDropdownItem,
                     )
-                        .icon-wrapper([innerHTML]='sanitizeIcon(item.icon)')
-                        .ml-3 {{item.title}}
+                        .icon-wrapper(
+                            *ngIf='hasIcons(button.submenuItems)',
+                            [innerHTML]='sanitizeIcon(item.icon)'
+                        )
+                        div([class.ml-3]='hasIcons(button.submenuItems)') {{item.title}}
 
             button.btn.btn-secondary.btn-tab-bar.btn-update(
                 *ngIf='updatesAvailable',

+ 4 - 0
terminus-core/src/components/appRoot.component.ts

@@ -250,6 +250,10 @@ export class AppRootComponent {
         }
     }
 
+    hasIcons (submenuItems: ToolbarButton[]): boolean {
+        return submenuItems.some(x => !!x.icon)
+    }
+
     sanitizeIcon (icon: string): any {
         return this.domSanitizer.bypassSecurityTrustHtml(icon || '')
     }

+ 0 - 4
terminus-core/src/components/checkbox.component.pug

@@ -1,4 +0,0 @@
-.icon(tabindex='0', [class.active]='model', (keyup.space)='click()')
-    i.fas.fa-square.off
-    i.fas.fa-check-square.on
-.text {{text}}

+ 0 - 55
terminus-core/src/components/checkbox.component.scss

@@ -1,55 +0,0 @@
-:host {
-    cursor: pointer;
-    margin: 5px 0;
-
-    &:focus {
-        background: rgba(255,255,255,.05);
-        border-radius: 5px;
-    }
-
-    &:active {
-        background: rgba(255,255,255,.1);
-        border-radius: 3px;
-    }
-
-    &[disabled] {
-        opacity: 0.5;
-    }
-
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-
-    .off {
-        color: rgba(0, 0, 0, .5);
-    }
-
-    .icon {
-        position: relative;
-        flex: none;
-        width: 14px;
-        height: 14px;
-
-        i {
-            position: absolute;
-            left: 0;
-            top: -2px;
-            transition: 0.25s opacity;
-            display: block;
-            font-size: 18px;
-        }
-
-        i.on, &.active i.off {
-            opacity: 0;
-        }
-
-        i.off, &.active i.on {
-            opacity: 1;
-        }
-    }
-
-    .text {
-        flex: auto;
-        margin-left: 8px;
-    }
-}

+ 6 - 2
terminus-core/src/components/checkbox.component.ts

@@ -4,8 +4,12 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
 /** @hidden */
 @Component({
     selector: 'checkbox',
-    template: require('./checkbox.component.pug'),
-    styles: [require('./checkbox.component.scss')],
+    template: `
+        <div class="custom-control custom-checkbox">
+            <input type="checkbox" class="custom-control-input" [(ngModel)]='model'>
+            <label class="custom-control-label">{{text}}</label>
+        </div>
+    `,
     providers: [
         { provide: NG_VALUE_ACCESSOR, useExisting: CheckboxComponent, multi: true },
     ],

+ 1 - 1
terminus-core/src/components/tabHeader.component.scss

@@ -48,7 +48,7 @@ $tabs-height: 38px;
         width: $button-size;
         height: $button-size;
         border-radius: $button-size / 2;
-        line-height: $button-size * 0.9;
+        line-height: $button-size;
         align-self: center;
         margin-right: 10px;
 

+ 0 - 47
terminus-core/src/components/toggle.component.scss

@@ -16,55 +16,8 @@
     padding-left: 10px;
     margin-left: -10px;
 
-    &:focus {
-        background: rgba(255,255,255,.05);
-        border-radius: 5px;
-    }
-
     &[disabled] {
         opacity: 0.5;
     }
 
-    .body {
-        $border-width: 2px;
-        border-radius: 5px;
-        border: $border-width solid rgba(255, 255, 255, .2);
-        padding: $padding;
-        height: $toggle-size + $border-width * 2 + $padding * 2;
-        width: $toggle-size * 2 + $border-width * 2 + $padding * 2;
-
-        position: relative;
-
-        .toggle {
-            position: absolute;
-            border-radius: 2px;
-            width: $toggle-size;
-            height: $toggle-size;
-            background: #475158;
-            top: $padding;
-            left: $padding;
-            transition: 0.25s left;
-            line-height: 19px;
-            text-align: center;
-            font-size: 10px;
-
-            i {
-                opacity: 0;
-                transition: 0.25s opacity;
-            }
-        }
-    }
-
-    &.active .body .toggle {
-        left: $toggle-size + $padding;
-
-        i {
-            color: white;
-            opacity: 1;
-        }
-    }
-
-    &:active {
-        background: rgba(255,255,255,.1);
-    }
 }

+ 4 - 7
terminus-core/src/components/toggle.component.ts

@@ -6,13 +6,10 @@ import { CheckboxComponent } from './checkbox.component'
 @Component({
     selector: 'toggle',
     template: `
-      <div class="switch">
-        <div class="body">
-          <div class="toggle" [class.bg-primary]='model'>
-            <i class="fa fa-check"></i>
-          </div>
-        </div>
-      </div>
+    <div class="custom-control custom-switch">
+      <input type="checkbox" class="custom-control-input" [(ngModel)]='model'>
+      <label class="custom-control-label"></label>
+    </div>
     `,
     styles: [require('./toggle.component.scss')],
     providers: [

+ 104 - 121
terminus-core/src/theme.scss

@@ -1,102 +1,10 @@
-$tab-border-radius: 5px;
-$button-hover-bg: rgba(0, 0, 0, .25);
-$button-active-bg: rgba(0, 0, 0, .5);
+@import "./theme.vars";
 
+// ---------
 
-$white:  #fff !default;
-$black:  #000 !default;
-$red:    #d9534f !default;
-$orange: #f0ad4e !default;
-$yellow: #ffd500 !default;
-$green:  #5cb85c !default;
-$blue:   #0275d8 !default;
-$teal:   #5bc0de !default;
-$pink:   #ff5b77 !default;
-$purple: #613d7c !default;
-
-$theme-colors: (
-    "primary":    $blue,
-    "secondary": #394b5d
-);
-
-$content-bg: rgba(39, 49, 60, 0.65); //#1D272D;
-$content-bg-solid: #1D272D;
-$body-bg: #131d27;
-$body-bg2: #20333e;
-
-$body-color: #ccc;
-$font-family-sans-serif: "Source Sans Pro";
-$font-family-monospace: "Source Code Pro";
-$font-size-base: 14rem / 16;
-
-$btn-border-radius: 0;
-$btn-secondary-color:            #ccc;
-$btn-secondary-bg:               #222;
-$btn-secondary-border:           #444;
-
-//$btn-warning-bg:                 rgba($orange, .5);
-
-
-$nav-tabs-border-width:                       0;
-$nav-tabs-border-radius:                      0;
-$nav-tabs-link-hover-border-color:            $body-bg;
-$nav-tabs-active-link-hover-color:            $white;
-$nav-tabs-active-link-hover-bg:               $blue;
-$nav-tabs-active-link-hover-border-color:     darken($blue, 30%);
-$nav-pills-border-radius:  0;
-
-$input-bg:                       #111;
-$input-disabled-bg:              #333;
-
-$input-color:                    $body-color;
-$input-color-placeholder:        #333;
-$input-border-color:             #344;
-$input-border-width: 1px;
-//$input-box-shadow:               inset 0 1px 1px rgba($black,.075);
-$input-border-radius:            0;
-$custom-select-border-radius: 0;
-$input-bg-focus:                 $input-bg;
-$input-border-focus:             lighten($blue, 25%);
-$input-focus-box-shadow:         none;
-$input-color-focus:              $input-color;
-$input-group-addon-bg:           $body-bg;
-$input-group-addon-border-color: $input-border-color;
-
-$modal-content-bg:               $content-bg-solid;
-$modal-content-border-color:     $body-bg;
-$modal-header-border-color:      transparent;
-$modal-footer-border-color:      transparent;
-
-$popover-bg:                     $body-bg;
-
-$dropdown-bg:                    $body-bg;
-$dropdown-link-color:            $body-color;
-$dropdown-link-hover-color:      white;
-$dropdown-link-hover-bg:         $body-bg2;
-//$dropdown-link-active-color:     $component-active-color;
-//$dropdown-link-active-bg:        $component-active-bg;
-$dropdown-link-disabled-color:   #333;
-$dropdown-header-color:          #333;
-
-$list-group-color: $body-color;
-$list-group-bg: rgba(255,255,255,.05);
-$list-group-border-color:  rgba(255,255,255,.1);
-$list-group-hover-bg: rgba(255,255,255,.1);
-$list-group-link-active-bg: rgba(255,255,255,.2);
-
-$list-group-action-color: $body-color;
-$list-group-action-bg: rgba(255,255,255,.05);
-$list-group-action-active-bg: $list-group-link-active-bg;
-
-$pre-bg: $dropdown-bg;
-$pre-color: $dropdown-link-color;
-
-$alert-danger-bg: $body-bg;
-$alert-danger-text: $red;
-$alert-danger-border: $red;
-
-$headings-font-weight: lighter;
-$headings-color: #eee;
+
+$button-hover-bg: rgba(0, 0, 0, .25);
+$button-active-bg: rgba(0, 0, 0, .5);
 
 @import '~bootstrap/scss/bootstrap.scss';
 
@@ -236,13 +144,14 @@ settings-tab > ngb-tabset {
             border: none;
             padding: 10px 50px 10px 20px;
             font-size: 14px;
+            border-radius: 0;
 
             &:not(.active) {
-              color: $body-color;
+                color: $body-color;
 
-              &:hover {
-                  color: $white;
-              }
+                &:hover {
+                    color: $white;
+                }
             }
         }
     }
@@ -310,14 +219,6 @@ hotkey-input-modal {
     margin-bottom: 2px;
 }
 
-.nav-tabs {
-    background: $btn-secondary-bg;
-    .nav-link {
-        transition: 0.25s all;
-        border-bottom-color: $nav-tabs-border-color;
-    }
-}
-
 ngb-tabset .tab-content {
     padding-top: 20px;
 }
@@ -361,22 +262,10 @@ ngb-tabset .tab-content {
     }
 }
 
-select.form-control {
-  -webkit-appearance: none;
-  background-image: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 24 24'><path fill='#444' d='M7.406 7.828l4.594 4.594 4.594-4.594 1.406 1.406-6 6-6-6z'></path></svg>");
-  background-position: 100% 50%;
-  background-repeat: no-repeat;
-  padding-right: 30px;
-}
-
 checkbox i.on {
     color: $blue;
 }
 
-toggle.active .body .toggle {
-    background: $blue;
-}
-
 .modal .modal-footer {
     background: rgba(0, 0, 0, .25);
 
@@ -409,3 +298,97 @@ toggle.active .body .toggle {
 search-panel {
     background: rgba(39, 49, 60, 0.65) !important;
 }
+
+
+.btn {
+    cursor: pointer;
+    justify-content: flex-start;
+    overflow: hidden;
+
+    &.disabled,
+    &:disabled {
+        cursor: not-allowed;
+    }
+}
+
+.btn.btn-outline-secondary {
+    @include button-outline-variant(#9badb9, #fff);
+    &:hover:not([disabled]), &:active:not([disabled]), &.active:not([disabled]) {
+        background-color: #3f484e;
+        border-color: darken(#9badb9, 25%);
+    }
+
+    border-color: darken(#9badb9, 25%);
+
+    &.disabled,
+    &:disabled {
+        color: #9badb9;
+    }
+}
+
+.btn-warning:not(:disabled):not(.disabled) {
+    &.active, &:active {
+        color: $gray-900;
+    }
+}
+
+.btn-secondary:not(:disabled):not(.disabled) {
+    &.active, &:active {
+        background: #191e23;
+    }
+}
+
+.btn-link {
+    &:hover, &[aria-expanded=true], &:active, &.active {
+        color: $link-hover-color;
+        border-radius: $btn-border-radius;
+    }
+
+    &[aria-expanded=true], &:active, &.active {
+        background: rgba(255, 255, 255, 0.1);
+    }
+}
+
+.btn-group .btn.active {
+    border-color: transparent !important;
+}
+
+.nav-tabs {
+    margin-bottom: 10px;
+
+    &.nav-justified .nav-link {
+        margin-right: 5px;
+    }
+
+    .nav-link {
+        border: none;
+        border-bottom: $nav-tabs-border-width solid transparent;
+        text-transform: uppercase;
+        font-weight: bold;
+        padding: 5px 0;
+        margin-right: 20px;
+
+        uib-tab-heading > i {
+            font-size: 18px;
+        }
+
+        @include hover-focus {
+            color: $nav-tabs-link-active-color;
+        }
+
+        &.disabled {
+            color: $nav-link-disabled-color;
+            border-color: transparent;
+        }
+    }
+
+    .nav-item:last-child .nav-link {
+        margin-right: 0;
+    }
+
+    .nav-link.active,
+    .nav-item.show .nav-link {
+        color: $nav-tabs-link-active-color;
+        border-color: $nav-tabs-link-active-border-color;
+    }
+}

+ 187 - 0
terminus-core/src/theme.vars.scss

@@ -0,0 +1,187 @@
+$white:    #fff;
+$gray-100: #f8f9fa;
+$gray-200: #e9ecef;
+$gray-300: #dee2e6;
+$gray-400: #ced4da;
+$gray-500: #adb5bd;
+$gray-600: #6c757d;
+$gray-700: #495057;
+$gray-800: #343a40;
+$gray-900: #212529;
+$black:    #000;
+
+
+$red:    #d9534f !default;
+$orange: #f0ad4e !default;
+$yellow: #ffd500 !default;
+$green:  #5cb85c !default;
+$blue:   #0275d8 !default;
+$teal:   #5bc0de !default;
+$pink:   #ff5b77 !default;
+$purple: #613d7c !default;
+
+
+@import "~bootstrap/scss/functions";
+
+$content-bg: rgba(39, 49, 60, 0.65); //#1D272D;
+$content-bg-solid: #1D272D;
+
+$table-bg: rgba(255,255,255,.05);
+$table-bg-hover: rgba(255,255,255,.1);
+$table-border-color: rgba(255,255,255,.1);
+
+$theme-colors: (
+  primary: $blue,
+  secondary: #38434e,
+  success: $green,
+  info: $blue,
+  warning: $orange,
+  danger: $red,
+  light: $gray-300,
+  dark: $gray-800,
+  rare: $purple
+);
+
+$body-color: #ccc;
+$body-bg: #131d27;
+$body-bg2: #20333e;
+
+
+$font-family-sans-serif: "Source Sans Pro";
+$font-family-monospace: "Source Code Pro";
+$font-size-base: 14rem / 16;
+$font-size-lg: 1.28rem;
+$font-size-sm: .85rem;
+
+$line-height-base: 1.6;
+
+$headings-color: #ced9e2;
+$headings-font-weight: lighter;
+
+$input-btn-padding-y: .3rem;
+$input-btn-padding-x: .9rem;
+$input-btn-line-height: 1.6;
+$input-btn-line-height-sm: 1.8;
+$input-btn-line-height-lg: 1.8;
+
+$btn-link-disabled-color: $gray-600;
+$btn-focus-box-shadow: none;
+
+$h4-font-size: 18px;
+
+$link-color: $gray-400;
+$link-hover-color: $white;
+$link-hover-decoration: none;
+
+$component-active-color: $white;
+$component-active-bg: #2f3a42;
+
+$list-group-bg: $table-bg;
+$list-group-border-color: $table-border-color;
+
+$list-group-item-padding-y: 0.8rem;
+$list-group-item-padding-x: 1rem;
+
+$list-group-hover-bg: $table-bg-hover;
+$list-group-active-bg: rgba(255,255,255,.2);
+$list-group-active-color: $component-active-color;
+$list-group-active-border-color: translate;
+
+$list-group-action-color: $body-color;
+$list-group-action-hover-color: white;
+
+$list-group-action-active-color: $component-active-color;
+$list-group-action-active-bg: $list-group-active-bg;
+
+$alert-padding-y: 0.9rem;
+$alert-padding-x: 1.25rem;
+
+$input-box-shadow: none;
+
+$transition-base: all .15s ease-in-out;
+$transition-fade: opacity .1s linear;
+$transition-collapse: height .35s ease;
+$btn-transition: all .15s ease-in-out;
+
+$popover-bg: $body-bg;
+$popover-body-color: $body-color;
+$popover-header-bg: $table-bg-hover;
+$popover-header-color: $headings-color;
+$popover-arrow-color: $popover-bg;
+$popover-max-width: 360px;
+
+$btn-border-width:  2px;
+
+$input-bg:                       #181e23;
+$input-disabled-bg:              #2e3235;
+
+$input-color:                    #ddd;
+$input-border-color:             $input-bg;
+$input-border-width:             2px;
+
+$input-focus-bg:                 $input-bg;
+$input-focus-border-color:       rgba(171, 171, 171, 0.61);
+$input-focus-color:              $input-color;
+
+$input-btn-focus-color: var(--focus-color);
+$input-btn-focus-box-shadow:  0 0 0 2px $input-btn-focus-color;
+
+$input-group-addon-color: $input-color;
+$input-group-addon-bg: $input-bg;
+$input-group-addon-border-color: transparent;
+$input-group-btn-border-color: $input-bg;
+
+$nav-tabs-border-radius: 0;
+$nav-tabs-border-color: transparent;
+$nav-tabs-border-width: 2px;
+$nav-tabs-link-hover-border-color: transparent;
+$nav-tabs-link-active-color: #eee;
+$nav-tabs-link-active-bg: transparent;
+$nav-tabs-link-active-border-color: #eee;
+
+$navbar-padding-y: 0;
+$navbar-padding-x: 0;
+
+$dropdown-bg: $table-bg;
+$dropdown-color: $body-color;
+$dropdown-border-width: 1px;
+$dropdown-box-shadow: 0 .5rem 1rem rgba($black,.175);
+$dropdown-header-color: $gray-500;
+
+$dropdown-link-color: $body-color;
+$dropdown-link-hover-color: #eee;
+$dropdown-link-hover-bg: rgba(255,255,255,.04);
+$dropdown-link-active-color: white;
+$dropdown-link-active-bg: rgba(0, 0, 0, .2);
+$dropdown-item-padding-y: 0.5rem;
+$dropdown-item-padding-x: 1.5rem;
+
+
+$code-color: $orange;
+$code-bg: rgba(0, 0, 0, .25);
+$code-padding-y: 3px;
+$code-padding-x: 5px;
+$pre-bg: $dropdown-bg;
+$pre-color: $dropdown-link-color;
+
+$badge-font-size: 0.75rem;
+$badge-font-weight: bold;
+$badge-padding-y: 4px;
+$badge-padding-x: 6px;
+
+
+$custom-control-indicator-size: 1.2rem;
+$custom-control-indicator-bg: $body-bg;
+$custom-control-indicator-border-color: lighten($body-bg, 25%);
+$custom-control-indicator-checked-bg: theme-color("primary");
+$custom-control-indicator-checked-color: $body-bg;
+$custom-control-indicator-checked-border-color: transparent;
+$custom-control-indicator-active-bg: rgba(255, 255, 0, 0.5);
+
+
+$modal-content-bg:               $content-bg-solid;
+$modal-content-border-color:     $body-bg;
+$modal-header-border-width:         0;
+$modal-footer-border-color:         #222;
+$modal-footer-border-width:         1px;
+$modal-content-border-width:        0;

+ 4 - 4
terminus-plugin-manager/src/components/pluginsSettingsTab.component.pug

@@ -5,7 +5,7 @@
 
 .d-flex
     h3.mb-1 Installed
-    button.btn.btn-outline-info.btn-sm.ml-auto((click)='openPluginsFolder()')
+    button.btn.btn-outline-secondary.btn-sm.ml-auto((click)='openPluginsFolder()')
         i.fas.fa-folder
         span Plugins folder
 
@@ -28,19 +28,19 @@
             i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
             span Upgrade ({{knownUpgrades[plugin.name].version}})
 
-        button.btn.btn-primary.ml-2(
+        button.btn.btn-link.text-primary.ml-2(
             *ngIf='config.store.pluginBlacklist.includes(plugin.name)',
             (click)='enablePlugin(plugin)'
         )
             i.fas.fa-fw.fa-play
 
-        button.btn.btn-secondary.ml-2(
+        button.btn.btn-link.ml-2(
             *ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
             (click)='disablePlugin(plugin)'
         )
             i.fas.fa-fw.fa-pause
 
-        button.btn.btn-danger.ml-2(
+        button.btn.btn-link.text-danger.ml-2(
             (click)='uninstallPlugin(plugin)',
             *ngIf='!plugin.isBuiltin',
             [disabled]='busy[plugin.name] != undefined'

+ 35 - 35
terminus-ssh/src/components/editConnectionModal.component.pug

@@ -1,69 +1,69 @@
 .modal-body
-    ngb-tabset(type='pills', [activeId]='basic')
+    ngb-tabset([activeId]='basic')
         ngb-tab(id='basic')
             ng-template(ngbTabTitle) General
             ng-template(ngbTabContent)
                 .form-group
                     label Name
                     input.form-control(
-                        type='text', 
-                        autofocus, 
-                        [(ngModel)]='connection.name', 
+                        type='text',
+                        autofocus,
+                        [(ngModel)]='connection.name',
                     )
 
                 .form-group
                     label Group
                     input.form-control(
-                        type='text', 
+                        type='text',
                         placeholder='Ungrouped',
-                        [(ngModel)]='connection.group', 
+                        [(ngModel)]='connection.group',
                     )
 
                 .form-group
                     label Host
                     input.form-control(
-                        type='text', 
-                        [(ngModel)]='connection.host', 
+                        type='text',
+                        [(ngModel)]='connection.host',
                     )
 
                 .form-group
                     label Port
                     input.form-control(
                         type='number',
-                        placeholder='22', 
-                        [(ngModel)]='connection.port', 
+                        placeholder='22',
+                        [(ngModel)]='connection.port',
                     )
 
                 .form-group
                     label Username
                     input.form-control(
-                        type='text', 
-                        [(ngModel)]='connection.user', 
+                        type='text',
+                        [(ngModel)]='connection.user',
                     )
-                    
+
                 .form-line
                     .header
                         .title Password
                         .description(*ngIf='!hasSavedPassword') Save a password in the keychain
                         .description(*ngIf='hasSavedPassword') There is a saved password for this connection
-                    button.btn.btn-outline-success.ml-4(*ngIf='!hasSavedPassword', (click)='setPassword()') 
-                        i.fas.fa-key 
+                    button.btn.btn-outline-success.ml-4(*ngIf='!hasSavedPassword', (click)='setPassword()')
+                        i.fas.fa-key
                         span Set password
-                    button.btn.btn-danger.ml-4(*ngIf='hasSavedPassword', (click)='clearSavedPassword()') 
+                    button.btn.btn-danger.ml-4(*ngIf='hasSavedPassword', (click)='clearSavedPassword()')
                         i.fas.fa-trash-alt
                         span Forget
-                    
+
                 .form-line
                     .header
-                        .title Private key 
+                        .title Private key
                         .description Path to the private key file
                     .input-group
                         input.form-control(
-                            type='text', 
-                            placeholder='Key file path', 
+                            type='text',
+                            placeholder='Key file path',
                             [(ngModel)]='connection.privateKey'
                         )
-                        .input-group-btn
+                        .input-group-append
                             button.btn.btn-secondary((click)='selectPrivateKey()')
                                 i.fas.fa-folder-open
 
@@ -73,27 +73,27 @@
                 .form-group
                     label Keep Alive Interval (Milliseconds)
                     input.form-control(
-                        type='number', 
-                        placeholder='0', 
-                        [(ngModel)]='connection.keepaliveInterval', 
+                        type='number',
+                        placeholder='0',
+                        [(ngModel)]='connection.keepaliveInterval',
                     )
 
                 .form-group
                     label Max Keep Alive Count
                     input.form-control(
-                        type='number', 
-                        placeholder='3', 
-                        [(ngModel)]='connection.keepaliveCountMax', 
+                        type='number',
+                        placeholder='3',
+                        [(ngModel)]='connection.keepaliveCountMax',
                     )
 
                 .form-group
                     label Ready Timeout (Milliseconds)
                     input.form-control(
-                        type='number', 
-                        placeholder='20000', 
-                        [(ngModel)]='connection.readyTimeout', 
+                        type='number',
+                        placeholder='20000',
+                        [(ngModel)]='connection.readyTimeout',
                     )
-                    
+
                 .form-group
                     label Ciphers
                     div(*ngFor='let alg of supportedAlgorithms.cipher')
@@ -128,12 +128,12 @@
                     tr(*ngFor='let script of connection.scripts')
                         td.pr-2
                             input.form-control(
-                                type='text', 
+                                type='text',
                                 [(ngModel)]='script.expect'
                             )
                         td
                             input.form-control(
-                                type='text', 
+                                type='text',
                                 [(ngModel)]='script.send'
                             )
                         td.pl-2
@@ -152,11 +152,11 @@
                                     i.fas.fa-arrow-down
                                 button.btn.btn-outline-danger.ml-0((click)='deleteScript(script)')
                                     i.fas.fa-trash
-                
+
                 button.btn.btn-outline-info.mt-2((click)='addScript()')
                     i.fas.fa-plus
                     span New item
-    
+
 .modal-footer
     button.btn.btn-outline-primary((click)='save()') Save
     button.btn.btn-outline-danger((click)='cancel()') Cancel

+ 24 - 21
terminus-terminal/src/components/appearanceSettingsTab.component.pug

@@ -1,24 +1,11 @@
 h3.mb-3 Appearance
 .d-flex
     .mr-5
-        .form-line
-            .header
-                .title Frontend
-                .description Switches terminal frontend implementation (experimental)
-
-            select.form-control(
-                [(ngModel)]='config.store.terminal.frontend',
-                (ngModelChange)='config.save()',
-            )
-                option(value='hterm') hterm
-                option(value='xterm') xterm
-                option(value='xterm-webgl') xterm (WebGL)
-
         .form-line
             .header
                 .title Font
 
-            .d-flex.w-75
+            .input-group.w-75
                 input.form-control.w-75(
                     type='text',
                     [ngbTypeahead]='fontAutocomplete',
@@ -52,9 +39,10 @@ h3.mb-3 Appearance
                 )
                     option(*ngFor='let scheme of config.store.terminal.customColorSchemes', [ngValue]='scheme') Custom: {{scheme.name}}
                     option(*ngFor='let scheme of colorSchemes', [ngValue]='scheme') {{scheme.name}}
-                .input-group-btn
-                    button.btn.btn-secondary((click)='editScheme(config.store.terminal.colorScheme)') Edit
-                .input-group-btn
+                .input-group-append
+                    button.btn.btn-secondary((click)='editScheme(config.store.terminal.colorScheme)')
+                        i.fas.fa-pen
+                .input-group-append
                     button.btn.btn-outline-danger(
                         (click)='deleteScheme(config.store.terminal.colorScheme)',
                         *ngIf='isCustomScheme(config.store.terminal.colorScheme)'
@@ -65,10 +53,12 @@ h3.mb-3 Appearance
             label Editing
             .input-group
                 input.form-control(type='text', [(ngModel)]='editingColorScheme.name')
-                .input-group-btn
-                    button.btn.btn-secondary((click)='saveScheme()') Save
-                .input-group-btn
-                    button.btn.btn-secondary((click)='cancelEditing()') Cancel
+                .input-group-append
+                    button.btn.btn-secondary((click)='saveScheme()')
+                        i.fas.fa-check
+                .input-group-append
+                    button.btn.btn-secondary((click)='cancelEditing()')
+                        i.fas.fa-times
 
         .form-group(*ngIf='editingColorScheme')
             color-picker(
@@ -180,6 +170,19 @@ h3.mb-3 Appearance
                     span  rm -rf /
                     span([style.background-color]='config.store.terminal.colorScheme.cursor') &nbsp;
 
+.form-line
+    .header
+        .title Frontend
+        .description Switches terminal frontend implementation (experimental)
+
+    select.form-control(
+        [(ngModel)]='config.store.terminal.frontend',
+        (ngModelChange)='config.save()',
+    )
+        option(value='hterm') hterm
+        option(value='xterm') xterm
+        option(value='xterm-webgl') xterm (WebGL)
+
 .form-line
     .header
         .title Terminal background

+ 16 - 16
terminus-terminal/src/components/editProfileModal.component.pug

@@ -2,55 +2,55 @@
     .form-group
         label Name
         input.form-control(
-            type='text', 
-            autofocus, 
-            [(ngModel)]='profile.name', 
+            type='text',
+            autofocus,
+            [(ngModel)]='profile.name',
         )
 
     .form-group
         label Command
         input.form-control(
-            type='text', 
-            [(ngModel)]='profile.sessionOptions.command', 
+            type='text',
+            [(ngModel)]='profile.sessionOptions.command',
         )
-    
+
     .form-group
         label Arguments
         .input-group(
             *ngFor='let arg of profile.sessionOptions.args; index as i; trackBy: trackByIndex',
         )
             input.form-control(
-                type='text', 
-                [(ngModel)]='profile.sessionOptions.args[i]', 
+                type='text',
+                [(ngModel)]='profile.sessionOptions.args[i]',
             )
-            .input-group-btn
+            .input-group-append
                 button.btn.btn-secondary((click)='profile.sessionOptions.args.splice(i, 1)')
                     i.fas.fa-trash
-        
+
         .mt-2
             button.btn.btn-secondary((click)='profile.sessionOptions.args.push("")')
                 i.fas.fa-plus.mr-2
                 | Add
-        
+
     .form-line(*ngIf='uac.isAvailable')
         .header
             .title Run as administrator
         toggle(
             [(ngModel)]='profile.sessionOptions.runAsAdministrator',
         )
-        
+
     .form-group
         label Working directory
         input.form-control(
-            type='text', 
-            [(ngModel)]='profile.sessionOptions.cwd', 
+            type='text',
+            [(ngModel)]='profile.sessionOptions.cwd',
         )
 
     .form-group
         label Environment
         environment-editor(
-            type='text', 
-            [(model)]='profile.sessionOptions.env', 
+            type='text',
+            [(model)]='profile.sessionOptions.env',
         )
 
 .modal-footer

+ 8 - 7
terminus-terminal/src/components/environmentEditor.component.pug

@@ -1,12 +1,13 @@
 .mb-2.d-flex.align-items-center(*ngFor='let pair of vars')
-    .input-group.w-50
-        input.form-control([(ngModel)]='pair.key', (blur)='emitUpdate()', placeholder='Variable name')
-        .input-group-append 
+    .input-group
+        input.form-control.w-25([(ngModel)]='pair.key', (blur)='emitUpdate()', placeholder='Variable name')
+        .input-group-append
             .input-group-text =
-    input.form-control.w-50.mr-1([(ngModel)]='pair.value', (blur)='emitUpdate()', placeholder='Value')
-    button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
-        i.fas.fa-trash
-        
+        input.form-control.w-50([(ngModel)]='pair.value', (blur)='emitUpdate()', placeholder='Value')
+        .input-group-append
+            button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
+                i.fas.fa-trash
+
 button.btn.btn-secondary((click)='addEnvironmentVar()')
     i.fas.fa-plus.mr-2
     span Add

+ 14 - 12
terminus-terminal/src/components/shellSettingsTab.component.pug

@@ -14,20 +14,20 @@ h3.mb-3 Shell
             [ngValue]='slug(profile.name).toLowerCase()'
         ) {{profile.name}}
 
-        
+
 .form-line(*ngIf='isConPTYAvailable')
     .header
         .title Use ConPTY
         .description Enables the experimental Windows ConPTY API
-        
+
     toggle(
         [(ngModel)]='config.store.terminal.useConPTY',
         (ngModelChange)='config.save()'
     )
-    
+
 .alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.useConPTY && isConPTYAvailable && !isConPTYStable')
     .mr-auto Windows 10 build 18309 or above is recommended for ConPTY
-    
+
 .alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.profile.startsWith("WSL") && (config.store.terminal.frontend != "hterm" || !config.store.terminal.useConPTY)')
     .mr-auto WSL terminal only supports TrueColor with ConPTY and the hterm frontend
 
@@ -50,15 +50,17 @@ h3.mb-3 Shell
             placeholder='Home directory',
             [(ngModel)]='config.store.terminal.workingDirectory',
             (ngModelChange)='config.save()',
-        )            
-        .input-group-btn
+        )
+        .input-group-append
             button.btn.btn-secondary((click)='pickWorkingDirectory()')
                 i.fas.fa-folder-open
 
 .form-line
     .header
         .title Always Use Working Directory
-        .description By default, new terminals will open where the previous terminal was working. Enabling this option will always launch new terminals in the working directory specified above.
+        .description
+            div By default, new terminals will open where the previous terminal was working.
+            div Enabling this option will always launch new terminals in the working directory specified above.
 
     toggle(
         [(ngModel)]='config.store.terminal.alwaysUseWorkingDirectory',
@@ -69,7 +71,7 @@ h3.mb-3 Shell
     .header
         .title Environment
         .description Inject additional environment variables
-        
+
     environment-editor([(model)]='this.config.store.terminal.environment')
 
 h3.mt-3 Saved Profiles
@@ -78,16 +80,16 @@ h3.mt-3 Saved Profiles
     .list-group-item.list-group-item-action.d-flex.align-items-center(
         *ngFor='let profile of config.store.terminal.profiles',
         (click)='editProfile(profile)',
-    ) 
+    )
         .mr-auto
             div {{profile.name}}
             .text-muted {{profile.sessionOptions.command}}
         button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)')
             i.fas.fa-trash
-                    
+
 div(ngbDropdown, placement='top-left')
-    button.btn.btn-primary(ngbDropdownToggle) 
+    button.btn.btn-primary(ngbDropdownToggle)
         i.fas.fa-fw.fa-plus
-        | New profile        
+        | New profile
     div(ngbDropdownMenu)
         button.dropdown-item(*ngFor='let shell of shells', (click)='newProfile(shell)') {{shell.name}}