mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Merge pull request #243 from paperless-ngx/css-variables
Custom color theming
This commit is contained in:
commit
8f1c4cd9c4
@ -19,7 +19,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
constructor (private settings: SettingsService, private consumerStatusService: ConsumerStatusService, private toastService: ToastService, private router: Router) {
|
||||
let anyWindow = (window as any)
|
||||
anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.js';
|
||||
this.settings.updateDarkModeSettings()
|
||||
this.settings.updateAppearanceSettings()
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
@ -92,7 +92,7 @@
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#file-text"/>
|
||||
</svg> {{d.title | documentTitle}}
|
||||
<span class="close bg-light" (click)="closeDocument(d); $event.preventDefault()">
|
||||
<span class="close" (click)="closeDocument(d); $event.preventDefault()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#x"/>
|
||||
</svg>
|
||||
@ -169,7 +169,7 @@
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<div class="d-flex w-100 flex-wrap">
|
||||
<a class="nav-link pe-0 pb-0" target="_blank" rel="noopener noreferrer" href="https://github.com/paperless-ngx/paperless-ngx">
|
||||
<a class="nav-link pe-2 pb-1" target="_blank" rel="noopener noreferrer" href="https://github.com/paperless-ngx/paperless-ngx">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="sidebaricon bi bi-github" viewBox="0 0 16 16">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
|
||||
</svg> <ng-container i18n>GitHub</ng-container>
|
||||
|
@ -35,16 +35,14 @@
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .sidebaricon {
|
||||
margin-right: 4px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: $primary;
|
||||
color: var(--bs-primary);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -172,8 +170,7 @@
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: #fff;
|
||||
color: #212529;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
flex-grow: 1;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<p *ngIf="message">{{message}}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-dark" (click)="cancel()" [disabled]="!buttonsEnabled" i18n>Cancel</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" [disabled]="!buttonsEnabled" i18n>Cancel</button>
|
||||
<button type="button" class="btn" [class]="btnClass" (click)="confirm()" [disabled]="!confirmButtonEnabled || !buttonsEnabled">
|
||||
{{btnCaption}}
|
||||
<span *ngIf="!confirmButtonEnabled"> ({{seconds}})</span>
|
||||
|
@ -42,7 +42,7 @@
|
||||
filter: brightness(0.5);
|
||||
|
||||
&.active {
|
||||
background-color: lighten($primary, 30%);
|
||||
background-color: var(--ngx-primary-lighten-30);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="mb-3">
|
||||
<label [for]="inputId">{{title}}</label>
|
||||
<label *ngIf="title" [for]="inputId">{{title}}</label>
|
||||
|
||||
<div class="input-group" [class.is-invalid]="error">
|
||||
<span class="input-group-text" [style.background-color]="value"> </span>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<app-widget-frame [title]="savedView.name">
|
||||
|
||||
<a header-buttons [routerLink]="[]" (click)="showAll()" i18n>Show all</a>
|
||||
<a class="btn-link" header-buttons [routerLink]="[]" (click)="showAll()" i18n>Show all</a>
|
||||
|
||||
|
||||
<table content class="table table-sm bg-light table-hover table-borderless mb-0">
|
||||
<table content class="table table-sm table-hover table-borderless mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th i18n>Created</th>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="card-body text-dark">
|
||||
<div class="card-body text-dark bg-light">
|
||||
<ng-content select ="[content]"></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">
|
||||
<ng-container *ngIf="document.correspondent">
|
||||
<a *ngIf="clickCorrespondent.observers.length ; else nolink" [routerLink]="[]" title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold">{{(document.correspondent$ | async)?.name}}</a>
|
||||
<a *ngIf="clickCorrespondent.observers.length ; else nolink" [routerLink]="[]" title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold btn-link">{{(document.correspondent$ | async)?.name}}</a>
|
||||
<ng-template #nolink>{{(document.correspondent$ | async)?.name}}</ng-template>:
|
||||
</ng-container>
|
||||
{{document.title | documentTitle}}
|
||||
|
@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
.card-selected {
|
||||
border-color: $primary;
|
||||
border-color: var(--bs-primary);
|
||||
|
||||
.document-card-check {
|
||||
display: block;
|
||||
@ -60,7 +60,7 @@
|
||||
}
|
||||
|
||||
.doc-img-background-selected {
|
||||
background-color: $primaryFaded;
|
||||
background-color: var(--ngx-primary-faded);
|
||||
}
|
||||
|
||||
.card-info {
|
||||
|
@ -23,7 +23,7 @@
|
||||
<div class="card-body p-2">
|
||||
<p class="card-text">
|
||||
<ng-container *ngIf="document.correspondent">
|
||||
<a [routerLink]="[]" title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold">{{(document.correspondent$ | async)?.name}}</a>:
|
||||
<a [routerLink]="[]" title="Filter by correspondent" i18n-title (click)="clickCorrespondent.emit(document.correspondent);$event.stopPropagation()" class="fw-bold btn-link">{{(document.correspondent$ | async)?.name}}</a>:
|
||||
</ng-container>
|
||||
{{document.title | documentTitle}}
|
||||
</p>
|
||||
|
@ -37,7 +37,7 @@
|
||||
}
|
||||
|
||||
.card-selected {
|
||||
border-color: $primary;
|
||||
border-color:var(--bs-primary);
|
||||
|
||||
.document-card-check {
|
||||
display: block;
|
||||
@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
.doc-img-background-selected {
|
||||
background-color: $primaryFaded;
|
||||
background-color: var(--ngx-primary-faded);
|
||||
}
|
||||
|
||||
.card-info {
|
||||
@ -57,7 +57,7 @@
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: transparent !important;
|
||||
color: $primary;
|
||||
color: var(--bs-primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ tr {
|
||||
}
|
||||
|
||||
.table-row-selected {
|
||||
background-color: $primaryFaded;
|
||||
background-color: var(--ngx-primary-faded);
|
||||
}
|
||||
|
||||
$paperless-card-breakpoints: (
|
||||
|
@ -11,7 +11,7 @@
|
||||
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></app-input-check>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -100,6 +100,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-3 col-form-label">
|
||||
<span i18n>Theme Color</span>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<app-input-color i18n-title formControlName="themeColor" [error]="error?.color"></app-input-color>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<button class="btn btn-link btn-sm pt-2 ps-0" [disabled]="!this.settingsForm.get('themeColor').value" (click)="clearThemeColor()">
|
||||
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x me-1" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
|
||||
</svg><ng-container i18n>Reset</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-4" i18n>Bulk editing</h4>
|
||||
|
||||
<div class="row mb-3">
|
||||
|
@ -24,6 +24,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
'darkModeUseSystem': new FormControl(null),
|
||||
'darkModeEnabled': new FormControl(null),
|
||||
'darkModeInvertThumbs': new FormControl(null),
|
||||
'themeColor': new FormControl(null),
|
||||
'useNativePdfViewer': new FormControl(null),
|
||||
'savedViews': this.savedViewGroup,
|
||||
'displayLanguage': new FormControl(null),
|
||||
@ -40,6 +41,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
store: BehaviorSubject<any>
|
||||
storeSub: Subscription
|
||||
isDirty$: Observable<boolean>
|
||||
isDirty: Boolean = false
|
||||
|
||||
get computedDateLocale(): string {
|
||||
return this.settingsForm.value.dateLocale || this.settingsForm.value.displayLanguage || this.currentLocale
|
||||
@ -63,6 +65,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
'darkModeUseSystem': this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM),
|
||||
'darkModeEnabled': this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED),
|
||||
'darkModeInvertThumbs': this.settings.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED),
|
||||
'themeColor': this.settings.get(SETTINGS_KEYS.THEME_COLOR),
|
||||
'useNativePdfViewer': this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER),
|
||||
'savedViews': {},
|
||||
'displayLanguage': this.settings.getLanguage(),
|
||||
@ -97,10 +100,21 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
|
||||
// Initialize dirtyCheck
|
||||
this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable())
|
||||
|
||||
// Record dirty in case we need to 'undo' appearance settings if not saved on close
|
||||
this.isDirty$.subscribe(dirty => {
|
||||
this.isDirty = dirty
|
||||
})
|
||||
|
||||
// "Live" visual changes prior to save
|
||||
this.settingsForm.valueChanges.subscribe(() => {
|
||||
this.settings.updateAppearanceSettings(this.settingsForm.get('darkModeUseSystem').value, this.settingsForm.get('darkModeEnabled').value, this.settingsForm.get('themeColor').value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.isDirty) this.settings.updateAppearanceSettings() // in case user changed appearance but didnt save
|
||||
this.storeSub && this.storeSub.unsubscribe();
|
||||
}
|
||||
|
||||
@ -119,6 +133,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
this.settings.set(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, this.settingsForm.value.darkModeUseSystem)
|
||||
this.settings.set(SETTINGS_KEYS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString())
|
||||
this.settings.set(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, (this.settingsForm.value.darkModeInvertThumbs == true).toString())
|
||||
this.settings.set(SETTINGS_KEYS.THEME_COLOR, (this.settingsForm.value.themeColor).toString())
|
||||
this.settings.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, this.settingsForm.value.useNativePdfViewer)
|
||||
this.settings.set(SETTINGS_KEYS.DATE_LOCALE, this.settingsForm.value.dateLocale)
|
||||
this.settings.set(SETTINGS_KEYS.DATE_FORMAT, this.settingsForm.value.dateFormat)
|
||||
@ -129,7 +144,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
this.settings.setLanguage(this.settingsForm.value.displayLanguage)
|
||||
this.store.next(this.settingsForm.value)
|
||||
this.documentListViewService.updatePageSize()
|
||||
this.settings.updateDarkModeSettings()
|
||||
this.settings.updateAppearanceSettings()
|
||||
this.toastService.showInfo($localize`Settings saved successfully.`)
|
||||
}
|
||||
|
||||
@ -165,4 +180,8 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
clearThemeColor() {
|
||||
this.settingsForm.get('themeColor').patchValue('');
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Inject, Injectable, LOCALE_ID, Renderer2, RendererFactory2 } from '@angular/core';
|
||||
import { Inject, Injectable, LOCALE_ID, Renderer2, RendererFactory2, RendererStyleFlags2 } from '@angular/core';
|
||||
import { Meta } from '@angular/platform-browser';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { hexToHsl } from 'src/app/utils/color';
|
||||
|
||||
export interface PaperlessSettings {
|
||||
key: string
|
||||
@ -27,6 +28,7 @@ export const SETTINGS_KEYS = {
|
||||
DARK_MODE_USE_SYSTEM: 'general-settings:dark-mode:use-system',
|
||||
DARK_MODE_ENABLED: 'general-settings:dark-mode:enabled',
|
||||
DARK_MODE_THUMB_INVERTED: 'general-settings:dark-mode:thumb-inverted',
|
||||
THEME_COLOR: 'general-settings:theme:color',
|
||||
USE_NATIVE_PDF_VIEWER: 'general-settings:document-details:native-pdf-viewer',
|
||||
DATE_LOCALE: 'general-settings:date-display:date-locale',
|
||||
DATE_FORMAT: 'general-settings:date-display:date-format',
|
||||
@ -43,6 +45,7 @@ const SETTINGS: PaperlessSettings[] = [
|
||||
{key: SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, type: "boolean", default: true},
|
||||
{key: SETTINGS_KEYS.DARK_MODE_ENABLED, type: "boolean", default: false},
|
||||
{key: SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, type: "boolean", default: true},
|
||||
{key: SETTINGS_KEYS.THEME_COLOR, type: "string", default: ""},
|
||||
{key: SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, type: "boolean", default: false},
|
||||
{key: SETTINGS_KEYS.DATE_LOCALE, type: "string", default: ""},
|
||||
{key: SETTINGS_KEYS.DATE_FORMAT, type: "string", default: "mediumDate"},
|
||||
@ -68,12 +71,13 @@ export class SettingsService {
|
||||
) {
|
||||
this.renderer = rendererFactory.createRenderer(null, null);
|
||||
|
||||
this.updateDarkModeSettings()
|
||||
this.updateAppearanceSettings()
|
||||
}
|
||||
|
||||
updateDarkModeSettings(): void {
|
||||
let darkModeUseSystem = this.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM)
|
||||
let darkModeEnabled = this.get(SETTINGS_KEYS.DARK_MODE_ENABLED)
|
||||
public updateAppearanceSettings(darkModeUseSystem = null, darkModeEnabled = null, themeColor = null): void {
|
||||
darkModeUseSystem ??= this.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM)
|
||||
darkModeEnabled ??= this.get(SETTINGS_KEYS.DARK_MODE_ENABLED)
|
||||
themeColor ??= this.get(SETTINGS_KEYS.THEME_COLOR);
|
||||
|
||||
if (darkModeUseSystem) {
|
||||
this.renderer.addClass(this.document.body, 'color-scheme-system')
|
||||
@ -83,6 +87,14 @@ export class SettingsService {
|
||||
darkModeEnabled ? this.renderer.addClass(this.document.body, 'color-scheme-dark') : this.renderer.removeClass(this.document.body, 'color-scheme-dark')
|
||||
}
|
||||
|
||||
if (themeColor) {
|
||||
const hsl = hexToHsl(themeColor)
|
||||
this.renderer.setStyle(document.documentElement, '--pngx-primary',`${+hsl.h * 360},${hsl.s * 100}%`, RendererStyleFlags2.DashCase)
|
||||
this.renderer.setStyle(document.documentElement, '--pngx-primary-lightness',`${hsl.l * 100}%`, RendererStyleFlags2.DashCase)
|
||||
} else {
|
||||
this.renderer.removeStyle(document.documentElement, '--pngx-primary', RendererStyleFlags2.DashCase)
|
||||
this.renderer.removeStyle(document.documentElement, '--pngx-primary-lightness', RendererStyleFlags2.DashCase)
|
||||
}
|
||||
}
|
||||
|
||||
getLanguageOptions(): LanguageOption[] {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { HSL } from "ngx-color"
|
||||
|
||||
function componentToHex(c) {
|
||||
var hex = Math.floor(c).toString(16)
|
||||
@ -5,8 +6,8 @@ function componentToHex(c) {
|
||||
}
|
||||
|
||||
/**
|
||||
* https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
*
|
||||
* https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
* Converts an HSL color value to RGB. Conversion formula
|
||||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||||
* Assumes h, s, and l are contained in the set [0, 1] and
|
||||
@ -42,6 +43,46 @@ function hslToRgb(h, s, l){
|
||||
return [r * 255, g * 255, b * 255]
|
||||
}
|
||||
|
||||
/**
|
||||
* https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
* Converts an RGB color value to HSL. Conversion formula
|
||||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||||
* Assumes r, g, and b are contained in the set [0, 255] and
|
||||
* returns h, s, and l in the set [0, 1].
|
||||
*
|
||||
* @param Number r The red color value
|
||||
* @param Number g The green color value
|
||||
* @param Number b The blue color value
|
||||
* @return Array The HSL representation
|
||||
*/
|
||||
export function rgbToHsl(r, g, b){
|
||||
r /= 255, g /= 255, b /= 255;
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
|
||||
if(max == min){
|
||||
h = s = 0; // achromatic
|
||||
}else{
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch(max){
|
||||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: h = (b - r) / d + 2; break;
|
||||
case b: h = (r - g) / d + 4; break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
return [h, s, l];
|
||||
}
|
||||
|
||||
export function hexToHsl(hex: string): HSL {
|
||||
hex = hex.replace('#', '')
|
||||
let aRgbHex = hex.match(/.{1,2}/g)
|
||||
const hsl = rgbToHsl(parseInt(aRgbHex[0], 16), parseInt(aRgbHex[1], 16), parseInt(aRgbHex[2], 16))
|
||||
return { h: hsl[0], s: hsl[1], l: hsl[2] }
|
||||
}
|
||||
|
||||
export function randomColor() {
|
||||
let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4)
|
||||
return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex(rgb[2])}`
|
||||
|
@ -1,8 +1,11 @@
|
||||
// bs options
|
||||
$enable-negative-margins: true;
|
||||
|
||||
@import "node_modules/bootstrap/scss/bootstrap";
|
||||
@import "~@ng-select/ng-select/themes/default.theme.css";
|
||||
@import "theme";
|
||||
@import "theme_dark";
|
||||
@import "print";
|
||||
@import "node_modules/bootstrap/scss/bootstrap";
|
||||
@import "~@ng-select/ng-select/themes/default.theme.css";
|
||||
|
||||
.toolbaricon {
|
||||
width: 1.2em;
|
||||
@ -113,10 +116,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.ngx-file-drop__drop-zone--over {
|
||||
background-color: $primaryFaded !important;
|
||||
}
|
||||
|
||||
// Bootstrap 5 tweaks
|
||||
a.badge {
|
||||
text-decoration: none;
|
||||
@ -130,6 +129,6 @@ a.badge {
|
||||
}
|
||||
|
||||
.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle {
|
||||
background-color: $paperless-green;
|
||||
border-color: $paperless-green;
|
||||
background-color: var(--bs-primary);
|
||||
border-color: var(--bs-primary);
|
||||
}
|
||||
|
@ -1,8 +1,294 @@
|
||||
$paperless-green: #17541f;
|
||||
$primary: #17541f;
|
||||
$primaryFaded: #d1ddd2;
|
||||
$enable-negative-margins: true;
|
||||
:root {
|
||||
// base color e.g. #17541f = hsl(128, 57%, 21%)
|
||||
--pngx-primary: 128, 57%;
|
||||
--pngx-primary-lightness: 21%;
|
||||
|
||||
--bs-primary: hsl(var(--pngx-primary), var(--pngx-primary-lightness));
|
||||
--bs-border-color: var(--bs-gray-400);
|
||||
--ngx-primary-faded: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 72%));
|
||||
--ngx-primary-lighten-10: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 10%));
|
||||
--ngx-primary-lighten-30: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 30%));
|
||||
--ngx-primary-darken-10: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 10%));
|
||||
--ngx-primary-darken-15: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 15%));
|
||||
--ngx-primary-darken-18: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 18%));
|
||||
--ngx-bg-darker: var(--bs-gray-100);
|
||||
--ngx-focus-alpha: 0.3;
|
||||
}
|
||||
|
||||
svg.logo {
|
||||
.leaf {
|
||||
fill: var(--bs-primary) !important;
|
||||
}
|
||||
.text {
|
||||
fill: var(--bs-body-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link, .list-group-item {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.bg-body {
|
||||
background-color: #fff;
|
||||
background-color: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: var(--bs-primary) !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--bs-primary);
|
||||
border-color: var(--bs-primary);
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--ngx-primary-darken-10);
|
||||
border-color: var(--ngx-primary-darken-10);
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
background-color: var(--ngx-primary-darken-10) !important;
|
||||
border-color: var(--ngx-primary-darken-10) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
border-color: var(--bs-primary) !important;
|
||||
color: var(--bs-primary) !important;
|
||||
|
||||
&:hover, &:focus, &.active, &:active {
|
||||
background-color: var(--bs-primary) !important;
|
||||
color: var(--bs-light) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-outline-secondary {
|
||||
color: var(--bs-secondary);
|
||||
}
|
||||
|
||||
.nav-item .sidebaricon {
|
||||
color: var(--bs-secondary);
|
||||
}
|
||||
|
||||
.btn:focus,
|
||||
.btn:active:focus,
|
||||
.dropdown-item:focus,
|
||||
.btn-check:focus + .btn,
|
||||
.form-control:focus,
|
||||
.form-check-input:focus,
|
||||
.form-check-radio:focus,
|
||||
.form-select:focus {
|
||||
box-shadow: 0 0 0 0.25rem hsla(var(--pngx-primary), var(--pngx-primary-lightness), var(--ngx-focus-alpha));
|
||||
}
|
||||
|
||||
.form-switch .form-check-input:focus {
|
||||
background-image: escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#bbb'/></svg>"));
|
||||
}
|
||||
|
||||
.nav-link:focus-visible, .nav-item a:focus-visible {
|
||||
outline: none;
|
||||
background-color: var(--ngx-bg-darker);
|
||||
}
|
||||
|
||||
a.navbar-brand:focus-visible {
|
||||
outline: none;
|
||||
color: var(--ngx-primary-darken-10);
|
||||
}
|
||||
|
||||
.dropdown.show {
|
||||
> .btn-primary {
|
||||
background-color: var(--bs-primary);
|
||||
border-color: var(--bs-primary);
|
||||
}
|
||||
|
||||
> .btn-outline-primary {
|
||||
color: var(--bs-body-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
a, a:hover, .btn-link, .btn-link:hover {
|
||||
color: var(--bs-primary);
|
||||
}
|
||||
|
||||
.form-control:not(.btn),
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
.form-select:not(.is-invalid):not(:disabled),
|
||||
.form-check-input {
|
||||
color: var(--bs-body-color);
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color);
|
||||
|
||||
&:focus {
|
||||
background-color: var(--ngx-bg-darker);
|
||||
color: var(--bs-body-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-input:checked {
|
||||
background-color: var(--bs-primary);
|
||||
border-color: var(--bs-primary);
|
||||
}
|
||||
|
||||
.form-check-input:focus {
|
||||
border-color: var(--bs-primary);
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: var(--bs-light);
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color) !important;
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--bs-primary) !important;
|
||||
color: var(--bs-light) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.page-item.active .page-link {
|
||||
background-color: var(--bs-primary);
|
||||
border-color: var(--bs-primary) !important;
|
||||
color: var(--bs-light);
|
||||
}
|
||||
|
||||
.page-item.disabled .page-link {
|
||||
background-color: var(--ngx-bg-darker);
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
|
||||
.nav-link {
|
||||
color: var(--bs-primary);
|
||||
|
||||
&.active, &:hover {
|
||||
border-color: var(--bs-border-color);
|
||||
background-color: var(--bs-body-bg);
|
||||
color: var(--bs-body-color);
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: var(--bs-border-color);
|
||||
}
|
||||
|
||||
&.active:focus, &:active {
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ng-select-container,
|
||||
.ng-select.ng-select-opened > .ng-select-container,
|
||||
.ng-dropdown-panel,
|
||||
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option {
|
||||
background-color: var(--bs-body-bg) !important;
|
||||
color: var(--bs-body-color) !important;
|
||||
border-color: var(--bs-border-color) !important;
|
||||
|
||||
input:focus {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
color: var(--bs-body-color);
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color);
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
color: var(--bs-body-color);
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color);
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--bs-body-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: var(--bs-body-bg);
|
||||
|
||||
.dropdown-divider {
|
||||
border-color: var(--bs-border-color);
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: var(--bs-body-color);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--ngx-bg-darker);
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: var(--bs-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.table {
|
||||
color: var(--bs-body-color);
|
||||
|
||||
.des,.asc {
|
||||
background-color: var(--bs-body-bg) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.modal .btn-close {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.ngx-file-drop__drop-zone--over {
|
||||
background-color: var(--ngx-primary-faded) !important;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
color: var(--bs-body-color);
|
||||
background-color: var(--bs-danger);
|
||||
border-color: var(--bs-danger);
|
||||
}
|
||||
|
||||
.alert-secondary {
|
||||
background-color: var(--ngx-primary-darken-18);
|
||||
border-color: var(--ngx-primary-darken-15);
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.ngb-dp-header,
|
||||
.ngb-dp-weekdays,
|
||||
.ngb-dp-month {
|
||||
background-color: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.popover {
|
||||
.popover-header,
|
||||
.popover-body {
|
||||
background-color: var(--ngx-bg-alt);
|
||||
border-color: var(--bs-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
// fix popover carat colors
|
||||
.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="left"] {
|
||||
border-left-color: var(--ngx-bg-alt);
|
||||
}
|
||||
.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="right"] {
|
||||
border-right-color: var(--ngx-bg-alt);
|
||||
}
|
||||
.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="top"] {
|
||||
border-top-color: var(--ngx-bg-alt);
|
||||
}
|
||||
.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="bottom"] {
|
||||
border-bottom-color: var(--ngx-bg-alt);
|
||||
}
|
||||
|
||||
.bs-popover-bottom .popover-header::before,
|
||||
.bs-popover-auto[x-placement^=bottom] .popover-header::before {
|
||||
border-bottom-color: var(--ngx-bg-alt);
|
||||
}
|
@ -1,8 +1,14 @@
|
||||
$primary-dark-mode: #45973a;
|
||||
$primary-dark-mode-rgb: 69, 151, 58;
|
||||
$primary-dark-mode-darken-10: darken($primary-dark-mode, 10%);
|
||||
$danger-dark-mode: #b71631;
|
||||
$danger-dark-mode-rgb: 183, 22, 49;
|
||||
$bg-dark-mode: #161618;
|
||||
$bg-dark-mode-accent: #21262d;
|
||||
$bg-dark-mode-rgb: 22, 22, 24;
|
||||
$bg-dark-mode-accent: #101216;
|
||||
$bg-dark-mode-alt: #242529;
|
||||
$bg-light-dark-mode: #1c1c1f;
|
||||
$bg-light-dark-mode-rgb: 28, 28, 31;
|
||||
$text-color-dark-mode: #abb2bf;
|
||||
$text-color-dark-mode-accent: lighten($text-color-dark-mode, 10%);
|
||||
$border-color-dark-mode: #47494f;
|
||||
@ -12,141 +18,79 @@ $border-color-dark-mode: #47494f;
|
||||
}
|
||||
|
||||
@mixin dark-mode {
|
||||
background-color: $bg-dark-mode !important;
|
||||
color: $text-color-dark-mode;
|
||||
--bs-primary: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 10%));
|
||||
--bs-danger: #{$danger-dark-mode};
|
||||
--bs-danger-rgb: #{$danger-dark-mode-rgb};
|
||||
--bs-body-bg: #{$bg-dark-mode};
|
||||
--bs-body-bg-rgb: #{$bg-dark-mode-rgb};
|
||||
--bs-body-color: #{$text-color-dark-mode};
|
||||
--bs-light: #{$bg-light-dark-mode};
|
||||
--bs-light-rgb: #{$bg-light-dark-mode-rgb};
|
||||
--bs-border-color: #{$border-color-dark-mode};
|
||||
--ngx-bg-darker: #{$bg-dark-mode-accent};
|
||||
--ngx-bg-alt: #{$bg-dark-mode-alt};
|
||||
--ngx-body-color-accent: #{$text-color-dark-mode-accent};
|
||||
--ngx-focus-alpha: 0.7;
|
||||
|
||||
.navbar.bg-primary{
|
||||
--bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness));
|
||||
--bs-primary-rgb: var(--bs-primary);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
color: $text-color-dark-mode;
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
svg.logo {
|
||||
.leaf {
|
||||
color: $primary-dark-mode !important;
|
||||
}
|
||||
.text {
|
||||
fill: $text-color-dark-mode !important;
|
||||
}
|
||||
}
|
||||
|
||||
.bg-light {
|
||||
background-color: $bg-light-dark-mode !important;
|
||||
|
||||
a,
|
||||
div {
|
||||
color: $text-color-dark-mode;
|
||||
}
|
||||
}
|
||||
|
||||
.bg-body {
|
||||
background-color: $bg-dark-mode !important;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: $text-color-dark-mode !important;
|
||||
}
|
||||
|
||||
|
||||
.border {
|
||||
border-color: $border-color-dark-mode !important;
|
||||
border-color: var(--bs-border-color) !important;
|
||||
}
|
||||
|
||||
.border-end {
|
||||
border-right: 1px solid $border-color-dark-mode !important;
|
||||
border-right: 1px solid var(--bs-border-color) !important;
|
||||
}
|
||||
|
||||
.border-start {
|
||||
border-left: 1px solid $border-color-dark-mode !important;
|
||||
border-left: 1px solid var(--bs-border-color) !important;
|
||||
}
|
||||
|
||||
.border-bottom {
|
||||
border-bottom: 1px solid $border-color-dark-mode !important;
|
||||
border-bottom: 1px solid var(--bs-border-color) !important;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: $text-color-dark-mode !important;
|
||||
.text-dark, .text-light {
|
||||
color: var(--bs-body-color) !important;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $bg-dark-mode;
|
||||
color: $text-color-dark-mode;
|
||||
border-color: $border-color-dark-mode $border-color-dark-mode $bg-dark-mode;
|
||||
|
||||
.close {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $text-color-dark-mode-accent !important;
|
||||
border-color: $border-color-dark-mode $border-color-dark-mode $bg-dark-mode;
|
||||
.btn-outline-primary, .btn-primary {
|
||||
&:hover, &:focus, &.active, &:active {
|
||||
color: var(--ngx-body-color-accent) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.page-item.active .page-link {
|
||||
background-color: darken($primary-dark-mode, 10%);
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-color: $border-color-dark-mode;
|
||||
|
||||
.nav-link {
|
||||
color: $primary-dark-mode !important;
|
||||
|
||||
&.active {
|
||||
color: $text-color-dark-mode !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: $bg-light-dark-mode;
|
||||
|
||||
.dropdown-divider {
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: $text-color-dark-mode;
|
||||
|
||||
&:hover {
|
||||
background-color: $bg-light-dark-mode;
|
||||
color: $text-color-dark-mode;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item.disabled {
|
||||
color: darken($text-color-dark-mode, 20%);
|
||||
.btn-outline-secondary {
|
||||
&:hover, &:focus, &.active, &:active {
|
||||
background-color: var(--ngx-bg-darker);
|
||||
color: var(--bs-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: $bg-light-dark-mode;
|
||||
background-color: var(--bs-body-bg);
|
||||
|
||||
.card-text {
|
||||
color: $text-color-dark-mode;
|
||||
.card-header {
|
||||
background-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
.text-dark {
|
||||
color: $text-color-dark-mode !important;
|
||||
}
|
||||
|
||||
.modal-content, .modal-header, .modal-body, .modal-footer {
|
||||
background-color: $bg-light-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color);
|
||||
}
|
||||
|
||||
app-tag .badge {
|
||||
filter: brightness(.8);
|
||||
}
|
||||
|
||||
.badge-light {
|
||||
background-color: darken($bg-dark-mode, 20%);
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
|
||||
.badge.border-light {
|
||||
border-color: $bg-dark-mode !important;
|
||||
}
|
||||
|
||||
.doc-img-container {
|
||||
border: none !important;
|
||||
border-top-left-radius: .25rem;
|
||||
@ -157,8 +101,9 @@ $border-color-dark-mode: #47494f;
|
||||
.doc-img {
|
||||
mix-blend-mode: normal;
|
||||
border-radius: 0;
|
||||
border-color: $bg-dark-mode;
|
||||
border-color: var(--bs-border-color);
|
||||
filter: invert(10%);
|
||||
|
||||
&.border-end {
|
||||
border-right: none !important;
|
||||
}
|
||||
@ -172,34 +117,14 @@ $border-color-dark-mode: #47494f;
|
||||
mix-blend-mode: luminosity;
|
||||
}
|
||||
|
||||
.toast {
|
||||
background-color: opacify($bg-light-dark-mode, .85);
|
||||
}
|
||||
|
||||
.toast-header {
|
||||
background-color: opacify($bg-dark-mode, .85);
|
||||
}
|
||||
|
||||
a,
|
||||
.card-title a {
|
||||
color: $primary-dark-mode;
|
||||
|
||||
&:hover {
|
||||
color: lighten($primary, 10%);
|
||||
}
|
||||
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option:hover,
|
||||
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked {
|
||||
background-color: $bg-light-dark-mode;
|
||||
}
|
||||
|
||||
table {
|
||||
background-color: $bg-dark-mode;
|
||||
color: $text-color-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
|
||||
.des,
|
||||
.asc {
|
||||
background-color: transparent !important;
|
||||
color: $text-color-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
|
||||
&::after {
|
||||
filter: invert(0.8); /* arrow is a black inline png bkgd image (!) so use filter */
|
||||
}
|
||||
@ -209,238 +134,31 @@ $border-color-dark-mode: #47494f;
|
||||
background-color: $bg-light-dark-mode;
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.table td,
|
||||
.table th {
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.table-row-selected {
|
||||
background-color: $bg-light-dark-mode;
|
||||
}
|
||||
|
||||
.table-striped > tbody > tr:nth-of-type(odd) > * {
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: $text-color-dark-mode;
|
||||
.close, .modal .btn-close {
|
||||
text-shadow: 0 1px 0 #666;
|
||||
}
|
||||
|
||||
.modal .btn-close {
|
||||
color: $text-color-dark-mode;
|
||||
text-shadow: 0 1px 0 #666;
|
||||
filter: invert(1) grayscale(100%) brightness(200%);
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
border-color: $primary-dark-mode;
|
||||
color: $primary-dark-mode;
|
||||
|
||||
&:not(:disabled):not(.disabled).active,
|
||||
&:not(:disabled):not(.disabled):hover {
|
||||
background-color: darken($primary-dark-mode, 10%);
|
||||
border-color: darken($primary-dark-mode, 10%);
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
|
||||
&.disabled.active {
|
||||
background-color: darken($primary-dark-mode, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-outline-secondary {
|
||||
border-color: darken($text-color-dark-mode, 30%);
|
||||
color: $text-color-dark-mode;
|
||||
|
||||
&:not(:disabled):not(.disabled):hover {
|
||||
background-color: $bg-dark-mode;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-outline-danger {
|
||||
border-color: $danger-dark-mode;
|
||||
color: $danger-dark-mode;
|
||||
|
||||
&:not(:disabled):not(.disabled):hover {
|
||||
background-color: darken($danger-dark-mode, 10%);
|
||||
border-color: darken($danger-dark-mode, 10%);
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-outline-dark {
|
||||
border-color: $border-color-dark-mode;
|
||||
color: $text-color-dark-mode;
|
||||
|
||||
&:not(:disabled):not(.disabled):hover {
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-light:not(:disabled):not(.disabled) {
|
||||
background-color: $bg-dark-mode;
|
||||
color: $text-color-dark-mode-accent;
|
||||
|
||||
&:hover {
|
||||
background-color: $text-color-dark-mode;
|
||||
color: $bg-dark-mode;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-link:not(:disabled):not(.disabled) {
|
||||
color: $primary-dark-mode;
|
||||
}
|
||||
|
||||
.btn-link:hover,
|
||||
.btn-outline-primary:not(:disabled):not(.disabled).active,
|
||||
.btn-outline-primary:not(:disabled):not(.disabled):active,
|
||||
.show > .btn-outline-primary.dropdown-toggle {
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
|
||||
button.bg-light:hover {
|
||||
background-color: $bg-dark-mode !important;
|
||||
}
|
||||
|
||||
.card-footer button:hover {
|
||||
color: $primary-dark-mode !important;
|
||||
}
|
||||
|
||||
.form-control:not(.is-invalid):not(.btn),
|
||||
input:not(.is-invalid),
|
||||
textarea:not(.is-invalid) {
|
||||
border-color: $border-color-dark-mode; /* we dont want to override controls that get highlighting for errors */
|
||||
}
|
||||
|
||||
.form-control:not(.btn),
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
background-color: $bg-dark-mode;
|
||||
color: $text-color-dark-mode;
|
||||
|
||||
&::placeholder {
|
||||
color: $text-color-dark-mode;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: $bg-light-dark-mode !important;
|
||||
color: darken($text-color-dark-mode, 10%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.form-select:not(.is-invalid):not(:disabled) {
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.ng-select-container,
|
||||
.ng-select.ng-select-opened > .ng-select-container,
|
||||
.ng-dropdown-panel,
|
||||
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option {
|
||||
background-color: $bg-dark-mode;
|
||||
color: $text-color-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
|
||||
input:focus {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option:hover,
|
||||
.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked {
|
||||
background-color: $bg-light-dark-mode;
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
color: $text-color-dark-mode;
|
||||
background-color: $bg-light-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
color: $text-color-dark-mode;
|
||||
background-color: $bg-light-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.page-item.disabled .page-link {
|
||||
background-color: $bg-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.page-link {
|
||||
background-color: $bg-light-dark-mode;
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.page-item.active .page-link {
|
||||
border-color: $border-color-dark-mode;
|
||||
color: $text-color-dark-mode-accent;
|
||||
}
|
||||
|
||||
.progress {
|
||||
background-color: $border-color-dark-mode;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
color: $text-color-dark-mode-accent;
|
||||
background-color: darken($danger-dark-mode, 20%);
|
||||
border-color: darken($danger-dark-mode, 20%);
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: $bg-light-dark-mode !important;
|
||||
}
|
||||
|
||||
.ngx-file-drop__drop-zone--over {
|
||||
background-color: darken($primary-dark-mode, 35%) !important;
|
||||
background-color: var(--ngx-primary-darken-15) !important;
|
||||
}
|
||||
|
||||
.alert-secondary {
|
||||
background-color: $bg-light-dark-mode;
|
||||
border-color: darken($bg-light-dark-mode, 10%);
|
||||
color: $text-color-dark-mode-accent;
|
||||
.toast {
|
||||
background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 18%), 0.9);
|
||||
}
|
||||
|
||||
.progress-bar.bg-primary {
|
||||
background-color: darken($primary-dark-mode, 5%) !important;
|
||||
}
|
||||
|
||||
.popover {
|
||||
.popover-header,
|
||||
.popover-body {
|
||||
background-color: $bg-dark-mode-accent;
|
||||
border-color: $border-color-dark-mode;
|
||||
}
|
||||
}
|
||||
|
||||
// fix popover carat colors
|
||||
.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="left"] {
|
||||
border-left-color: $bg-dark-mode-accent;
|
||||
}
|
||||
.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="right"] {
|
||||
border-right-color: $bg-dark-mode-accent;
|
||||
}
|
||||
.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="top"] {
|
||||
border-top-color: $bg-dark-mode-accent;
|
||||
}
|
||||
.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^="bottom"] {
|
||||
border-bottom-color: $bg-dark-mode-accent;
|
||||
}
|
||||
|
||||
.bs-popover-bottom .popover-header::before,
|
||||
.bs-popover-auto[x-placement^=bottom] .popover-header::before {
|
||||
border-bottom-color: $bg-dark-mode-accent;
|
||||
}
|
||||
|
||||
.ngb-dp-header,
|
||||
.ngb-dp-weekdays,
|
||||
.ngb-dp-month {
|
||||
background-color: $bg-light-dark-mode;
|
||||
|
||||
.toast-header {
|
||||
background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 10%), 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user