From d98a016087378cf44a51d4aa0dcd992369091b1e Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Tue, 12 Apr 2022 19:21:55 -0700
Subject: [PATCH 1/4] Initial build of primary color contrast
---
src-ui/src/app/services/settings.service.ts | 14 ++
src-ui/src/app/utils/color.ts | 19 +-
src-ui/src/styles.scss | 20 +-
src-ui/src/theme.scss | 192 ++++++++++++++++++++
src-ui/src/theme_dark.scss | 171 -----------------
5 files changed, 237 insertions(+), 179 deletions(-)
delete mode 100644 src-ui/src/theme_dark.scss
diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts
index b3447ee26..e9017d147 100644
--- a/src-ui/src/app/services/settings.service.ts
+++ b/src-ui/src/app/services/settings.service.ts
@@ -132,8 +132,22 @@ export class SettingsService {
: this.renderer.removeClass(this.document.body, 'color-scheme-dark')
}
+ // remove these in case they were there
+ this.renderer.removeClass(this.document.body, 'text-bg-dark')
+ this.renderer.removeClass(this.document.body, 'text-bg-light')
+
if (themeColor) {
const hsl = hexToHsl(themeColor)
+ const useDarkTextColor =
+ parseInt(themeColor.replace('#', ''), 16) > 0xffffff / 1.5
+
+ if (useDarkTextColor) {
+ this.renderer.addClass(this.document.body, 'text-bg-dark')
+ this.renderer.removeClass(this.document.body, 'text-bg-light')
+ } else {
+ this.renderer.addClass(this.document.body, 'text-bg-light')
+ this.renderer.removeClass(this.document.body, 'text-bg-dark')
+ }
this.renderer.setStyle(
document.documentElement,
'--pngx-primary',
diff --git a/src-ui/src/app/utils/color.ts b/src-ui/src/app/utils/color.ts
index 79d237f27..5c083c2b9 100644
--- a/src-ui/src/app/utils/color.ts
+++ b/src-ui/src/app/utils/color.ts
@@ -1,4 +1,4 @@
-import { HSL } from 'ngx-color'
+import { HSL, RGB } from 'ngx-color'
function componentToHex(c) {
var hex = Math.floor(c).toString(16)
@@ -86,14 +86,19 @@ export function rgbToHsl(r, g, b) {
}
export function hexToHsl(hex: string): HSL {
+ const rgb = hexToRGB(hex)
+ const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b)
+ return { h: hsl[0], s: hsl[1], l: hsl[2] }
+}
+
+export function hexToRGB(hex: string): RGB {
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] }
+ return {
+ r: parseInt(aRgbHex[0], 16),
+ g: parseInt(aRgbHex[1], 16),
+ b: parseInt(aRgbHex[2], 16),
+ }
}
export function randomColor() {
diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss
index 6c6d5f965..6922e3d7c 100644
--- a/src-ui/src/styles.scss
+++ b/src-ui/src/styles.scss
@@ -4,7 +4,6 @@ $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";
// Paperless-ngx styles
@@ -36,9 +35,19 @@ svg.logo {
.bg-primary {
background-color: var(--bs-primary) !important;
+ color: var(--pngx-primary-text-contrast);
+}
+
+.navbar-brand {
+ color: var(--pngx-primary-text-contrast) !important;
+}
+
+.navbar .dropdown .btn {
+ color: var(--pngx-primary-text-contrast) !important;
}
.btn-primary {
+ color: var(--pngx-primary-text-contrast);
background-color: var(--bs-primary);
border-color: var(--bs-primary);
@@ -48,6 +57,7 @@ svg.logo {
}
&:disabled, &.disabled {
+ color: var(--pngx-primary-text-contrast);
background-color: var(--pngx-primary-darken-10) !important;
border-color: var(--pngx-primary-darken-10) !important;
}
@@ -350,6 +360,14 @@ table.table {
}
}
+.toast {
+ color: var(--pngx-primary-text-contrast);
+
+ .toast-header {
+ color: var(--pngx-primary-text-contrast);
+ }
+}
+
.close {
color: var(--bs-body-color);
}
diff --git a/src-ui/src/theme.scss b/src-ui/src/theme.scss
index f52fba1f5..ea7995be8 100644
--- a/src-ui/src/theme.scss
+++ b/src-ui/src/theme.scss
@@ -15,3 +15,195 @@
--pngx-bg-darker: var(--bs-gray-100);
--pngx-focus-alpha: 0.3;
}
+
+// Dark text colors allow for maintain contrast with theme color changes
+$text-color-light-bg: #212529;
+$text-color-dark-bg: #abb2bf;
+$text-color-dark-bg-accent: lighten($text-color-dark-bg, 10%);
+// Taken from bootstrap
+$form-check-input-checked-bg-image-dark: url("data:image/svg+xml,");
+$form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,");
+
+.text-bg-light {
+ --pngx-primary-text-contrast: #{$text-color-light-bg} !important;
+
+ .form-check-input:checked[type=checkbox] {
+ background-image: escape-svg($form-check-input-checked-bg-image-dark);
+ }
+
+ .form-check-input:checked[type=radio] {
+ background-image: escape-svg($form-check-radio-checked-bg-image-dark);
+ }
+}
+
+.text-bg-dark {
+ --pngx-primary-text-contrast: #{$text-color-dark-bg} !important;
+}
+
+// Dark mode
+$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-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;
+$border-color-dark-mode: #47494f;
+
+@mixin dark-mode {
+ --bs-primary: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 10%));
+ --bs-body-color: #{$text-color-dark-bg};
+ --pngx-body-color-accent: #{$text-color-dark-bg-accent};
+ --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-light: #{$bg-light-dark-mode};
+ --bs-light-rgb: #{$bg-light-dark-mode-rgb};
+ --bs-border-color: #{$border-color-dark-mode};
+ --pngx-bg-darker: #{$bg-dark-mode-accent};
+ --pngx-bg-alt: #{$bg-dark-mode-alt};
+ --pngx-focus-alpha: 0.7;
+ --pngx-primary-faded: var(--pngx-primary-darken-15);
+ --pngx-primary-text-contrast: var(--bs-body-color);
+
+ .navbar.bg-primary {
+ --bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness));
+ --bs-primary-rgb: var(--bs-primary);
+ }
+
+ .border {
+ border-color: var(--bs-border-color) !important;
+ }
+
+ .border-end {
+ border-right: 1px solid var(--bs-border-color) !important;
+ }
+
+ .border-start {
+ border-left: 1px solid var(--bs-border-color) !important;
+ }
+
+ .border-bottom {
+ border-bottom: 1px solid var(--bs-border-color) !important;
+ }
+
+ .text-dark, .text-light {
+ color: var(--bs-body-color) !important;
+ }
+
+ .btn-outline-primary, .btn-primary {
+ &:hover, &:focus, &.active, &:active {
+ color: var(--bs-light) !important;
+ }
+ }
+
+ .btn-outline-secondary {
+ &:hover, &:focus, &.active, &:active {
+ background-color: var(--pngx-bg-darker);
+ color: var(--bs-primary);
+ }
+ }
+
+ .search-form-container {
+ input, input:focus {
+ color: var(--bs-body-color) !important;
+ }
+ }
+
+ .card {
+ background-color: var(--bs-body-bg);
+
+ .card-header {
+ background-color: rgba(0, 0, 0, 0.12);
+ }
+ }
+
+ .modal-content, .modal-header, .modal-body, .modal-footer {
+ background-color: var(--bs-body-bg);
+ border-color: var(--bs-border-color);
+ }
+
+ app-tag .badge {
+ filter: brightness(.8);
+ }
+
+ .doc-img-container {
+ border: none !important;
+ border-top-left-radius: .25rem;
+ border-top-right-radius: .25rem;
+ overflow: hidden;
+ }
+
+ .doc-img {
+ mix-blend-mode: normal;
+ border-radius: 0;
+ border-color: var(--bs-border-color);
+ filter: invert(10%);
+
+ &.border-end {
+ border-right: none !important;
+ }
+ }
+
+ .doc-img.inverted {
+ filter: invert(95%) hue-rotate(180deg);
+ }
+
+ .card-selected .doc-img {
+ mix-blend-mode: luminosity;
+ }
+
+ .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 {
+ .des,
+ .asc {
+ &::after {
+ filter: invert(0.8); /* arrow is a black inline png bkgd image (!) so use filter */
+ }
+ }
+
+ &.table-hover > tbody > tr:hover > * {
+ background-color: $bg-light-dark-mode;
+ color: var(--pngx-body-color-accent);
+ }
+
+ }
+
+ .table-striped > tbody > tr:nth-of-type(odd) > * {
+ color: var(--pngx-body-color-accent);
+ }
+
+ .close, .modal .btn-close, .alert .btn-close {
+ text-shadow: 0 1px 0 #666;
+ }
+
+ .modal .btn-close, .alert .btn-close {
+ filter: invert(1) grayscale(100%) brightness(200%);
+ }
+
+ .toast {
+ background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 18%), 0.9);
+ }
+
+ .toast-header {
+ background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 10%), 0.9);
+ }
+}
+
+body.color-scheme-dark {
+ @include dark-mode;
+}
+body.color-scheme-system {
+ @media (prefers-color-scheme: dark) {
+ @include dark-mode;
+ }
+}
diff --git a/src-ui/src/theme_dark.scss b/src-ui/src/theme_dark.scss
deleted file mode 100644
index 240312845..000000000
--- a/src-ui/src/theme_dark.scss
+++ /dev/null
@@ -1,171 +0,0 @@
-$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-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;
-
-@mixin 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};
- --pngx-bg-darker: #{$bg-dark-mode-accent};
- --pngx-bg-alt: #{$bg-dark-mode-alt};
- --pngx-body-color-accent: #{$text-color-dark-mode-accent};
- --pngx-focus-alpha: 0.7;
- --pngx-primary-faded: var(--pngx-primary-darken-15);
- --pngx-primary-text-contrast: var(--bs-body-color);
-
- .navbar.bg-primary{
- --bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness));
- --bs-primary-rgb: var(--bs-primary);
- }
-
- .navbar-brand {
- color: var(--bs-body-color);
- }
-
- .border {
- border-color: var(--bs-border-color) !important;
- }
-
- .border-end {
- border-right: 1px solid var(--bs-border-color) !important;
- }
-
- .border-start {
- border-left: 1px solid var(--bs-border-color) !important;
- }
-
- .border-bottom {
- border-bottom: 1px solid var(--bs-border-color) !important;
- }
-
- .text-dark, .text-light {
- color: var(--bs-body-color) !important;
- }
-
- .btn-outline-primary, .btn-primary {
- &:hover, &:focus, &.active, &:active {
- color: var(--bs-light) !important;
- }
- }
-
- .btn-outline-secondary {
- &:hover, &:focus, &.active, &:active {
- background-color: var(--pngx-bg-darker);
- color: var(--bs-primary);
- }
- }
-
- .search-form-container {
- input, input:focus {
- color: var(--bs-body-color) !important;
- }
- }
-
- .card {
- background-color: var(--bs-body-bg);
-
- .card-header {
- background-color: rgba(0, 0, 0, 0.12);
- }
- }
-
- .modal-content, .modal-header, .modal-body, .modal-footer {
- background-color: var(--bs-body-bg);
- border-color: var(--bs-border-color);
- }
-
- app-tag .badge {
- filter: brightness(.8);
- }
-
- .doc-img-container {
- border: none !important;
- border-top-left-radius: .25rem;
- border-top-right-radius: .25rem;
- overflow: hidden;
- }
-
- .doc-img {
- mix-blend-mode: normal;
- border-radius: 0;
- border-color: var(--bs-border-color);
- filter: invert(10%);
-
- &.border-end {
- border-right: none !important;
- }
- }
-
- .doc-img.inverted {
- filter: invert(95%) hue-rotate(180deg);
- }
-
- .card-selected .doc-img {
- mix-blend-mode: luminosity;
- }
-
- .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 {
- .des,
- .asc {
- &::after {
- filter: invert(0.8); /* arrow is a black inline png bkgd image (!) so use filter */
- }
- }
-
- &.table-hover > tbody > tr:hover > * {
- background-color: $bg-light-dark-mode;
- color: $text-color-dark-mode-accent;
- }
- }
-
- .table-striped > tbody > tr:nth-of-type(odd) > * {
- color: $text-color-dark-mode-accent;
- }
-
- .close, .modal .btn-close, .alert .btn-close {
- text-shadow: 0 1px 0 #666;
- }
-
- .modal .btn-close, .alert .btn-close {
- filter: invert(1) grayscale(100%) brightness(200%);
- }
-
- .toast {
- background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 18%), 0.9);
- }
-
- .toast-header {
- background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 10%), 0.9);
- }
-}
-
-body.color-scheme-dark {
- @include dark-mode;
-}
-body.color-scheme-system {
- @media (prefers-color-scheme: dark) {
- @include dark-mode;
- }
-}
From 1c2699b16ee122d9c0bcf88003ab659a47fb0b25 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Tue, 12 Apr 2022 22:23:00 -0700
Subject: [PATCH 2/4] Refactor contrast to use luminance function
---
src-ui/src/app/services/settings.service.ts | 11 +++++---
src-ui/src/app/utils/color.ts | 28 +++++++++++++++++++++
2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts
index e9017d147..747c21fb7 100644
--- a/src-ui/src/app/services/settings.service.ts
+++ b/src-ui/src/app/services/settings.service.ts
@@ -9,7 +9,11 @@ import {
} from '@angular/core'
import { Meta } from '@angular/platform-browser'
import { CookieService } from 'ngx-cookie-service'
-import { hexToHsl } from 'src/app/utils/color'
+import {
+ BRIGHTNESS,
+ estimateBrightnessForColor,
+ hexToHsl,
+} from 'src/app/utils/color'
export interface PaperlessSettings {
key: string
@@ -138,10 +142,9 @@ export class SettingsService {
if (themeColor) {
const hsl = hexToHsl(themeColor)
- const useDarkTextColor =
- parseInt(themeColor.replace('#', ''), 16) > 0xffffff / 1.5
+ const bgBrightnessEstimate = estimateBrightnessForColor(themeColor)
- if (useDarkTextColor) {
+ if (bgBrightnessEstimate == BRIGHTNESS.DARK) {
this.renderer.addClass(this.document.body, 'text-bg-dark')
this.renderer.removeClass(this.document.body, 'text-bg-light')
} else {
diff --git a/src-ui/src/app/utils/color.ts b/src-ui/src/app/utils/color.ts
index 5c083c2b9..e23a91c5f 100644
--- a/src-ui/src/app/utils/color.ts
+++ b/src-ui/src/app/utils/color.ts
@@ -1,5 +1,10 @@
import { HSL, RGB } from 'ngx-color'
+export const BRIGHTNESS = {
+ LIGHT: 'light',
+ DARK: 'dark',
+}
+
function componentToHex(c) {
var hex = Math.floor(c).toString(16)
return hex.length == 1 ? '0' + hex : hex
@@ -101,6 +106,29 @@ export function hexToRGB(hex: string): RGB {
}
}
+export function computeLuminance(color: RGB) {
+ // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ const colorKeys = Object.keys(color)
+ for (var i = 0; i < 3; i++) {
+ var rgb = color[colorKeys[i]]
+ rgb /= 255
+ rgb = rgb < 0.03928 ? rgb / 12.92 : Math.pow((rgb + 0.055) / 1.055, 2.4)
+ color[i] = rgb
+ }
+ return 0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2]
+}
+
+export function estimateBrightnessForColor(colorHex: string) {
+ // See
+ // Adapted from https://api.flutter.dev/flutter/material/ThemeData/estimateBrightnessForColor.html
+ const rgb = hexToRGB(colorHex)
+ const luminance = computeLuminance(rgb)
+ const kThreshold = 0.15
+ return (luminance + 0.05) * (luminance + 0.05) > kThreshold
+ ? BRIGHTNESS.LIGHT
+ : BRIGHTNESS.DARK
+}
+
export function randomColor() {
let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4)
return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex(
From 1d7ddcc10d38d71a61965f034b22b8c55bc91066 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Wed, 13 Apr 2022 08:43:35 -0700
Subject: [PATCH 3/4] Remove unneeded imports since change to css vars
---
src-ui/src/app/components/app-frame/app-frame.component.scss | 1 -
.../filterable-dropdown/filterable-dropdown.component.scss | 2 --
.../upload-file-widget/upload-file-widget.component.scss | 2 --
.../document-card-large/document-card-large.component.scss | 2 --
.../document-card-small/document-card-small.component.scss | 2 --
.../app/components/document-list/document-list.component.scss | 2 --
6 files changed, 11 deletions(-)
diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss
index bcf87a12a..5511a29b0 100644
--- a/src-ui/src/app/components/app-frame/app-frame.component.scss
+++ b/src-ui/src/app/components/app-frame/app-frame.component.scss
@@ -1,4 +1,3 @@
-@import "/src/theme";
/*
* Sidebar
*/
diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss
index a72473112..dfb989fea 100644
--- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss
+++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss
@@ -1,5 +1,3 @@
-@import "/src/theme";
-
.badge-corner {
position: absolute;
top: -8px;
diff --git a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss
index cd3afe46f..0e81d8bb5 100644
--- a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss
+++ b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss
@@ -1,5 +1,3 @@
-@import "/src/theme";
-
form {
position: relative;
}
diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss
index 33deebc37..e3398c245 100644
--- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss
+++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss
@@ -1,5 +1,3 @@
-@import "/src/theme";
-
.result-content {
overflow-wrap: anywhere;
}
diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss
index ae89ea9d6..4d03d0a4d 100644
--- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss
+++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss
@@ -1,5 +1,3 @@
-@import "/src/theme";
-
.card-text {
font-size: 90%;
}
diff --git a/src-ui/src/app/components/document-list/document-list.component.scss b/src-ui/src/app/components/document-list/document-list.component.scss
index 616069b08..b2d138d7f 100644
--- a/src-ui/src/app/components/document-list/document-list.component.scss
+++ b/src-ui/src/app/components/document-list/document-list.component.scss
@@ -1,5 +1,3 @@
-@import "/src/theme";
-
::ng-deep app-document-list app-page-header > div.mb-3 {
margin-bottom: 0 !important;
}
From 6478db13e6446c458e280609b029bf2bc99fa928 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Wed, 13 Apr 2022 09:29:23 -0700
Subject: [PATCH 4/4] miscellaneous css fixes / reorganization
---
.../app-frame/app-frame.component.scss | 7 +++-
src-ui/src/app/services/settings.service.ts | 12 +++---
src-ui/src/styles.scss | 40 +++++++++++++-----
src-ui/src/theme.scss | 42 ++++---------------
4 files changed, 50 insertions(+), 51 deletions(-)
diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss
index 5511a29b0..5fe408660 100644
--- a/src-ui/src/app/components/app-frame/app-frame.component.scss
+++ b/src-ui/src/app/components/app-frame/app-frame.component.scss
@@ -35,10 +35,15 @@
.sidebar .nav-link {
font-weight: 500;
- &:hover, &.active {
+ &:hover, &.active, &:focus {
color: var(--bs-primary);
}
+ &:focus-visible {
+ outline: none;
+ background-color: var(--bs-body-bg);
+ }
+
&.active {
font-weight: bold;
}
diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts
index 747c21fb7..a6e972168 100644
--- a/src-ui/src/app/services/settings.service.ts
+++ b/src-ui/src/app/services/settings.service.ts
@@ -137,19 +137,19 @@ export class SettingsService {
}
// remove these in case they were there
- this.renderer.removeClass(this.document.body, 'text-bg-dark')
- this.renderer.removeClass(this.document.body, 'text-bg-light')
+ this.renderer.removeClass(this.document.body, 'primary-dark')
+ this.renderer.removeClass(this.document.body, 'primary-light')
if (themeColor) {
const hsl = hexToHsl(themeColor)
const bgBrightnessEstimate = estimateBrightnessForColor(themeColor)
if (bgBrightnessEstimate == BRIGHTNESS.DARK) {
- this.renderer.addClass(this.document.body, 'text-bg-dark')
- this.renderer.removeClass(this.document.body, 'text-bg-light')
+ this.renderer.addClass(this.document.body, 'primary-dark')
+ this.renderer.removeClass(this.document.body, 'primary-light')
} else {
- this.renderer.addClass(this.document.body, 'text-bg-light')
- this.renderer.removeClass(this.document.body, 'text-bg-dark')
+ this.renderer.addClass(this.document.body, 'primary-light')
+ this.renderer.removeClass(this.document.body, 'primary-dark')
}
this.renderer.setStyle(
document.documentElement,
diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss
index 6922e3d7c..0838661ae 100644
--- a/src-ui/src/styles.scss
+++ b/src-ui/src/styles.scss
@@ -25,6 +25,27 @@ svg.logo {
}
}
+.navbar.bg-primary {
+ --bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness));
+ --bs-primary-rgb: var(--bs-primary);
+}
+
+.border {
+ border-color: var(--bs-border-color) !important;
+}
+
+.border-end {
+ border-right: 1px solid var(--bs-border-color) !important;
+}
+
+.border-start {
+ border-left: 1px solid var(--bs-border-color) !important;
+}
+
+.border-bottom {
+ border-bottom: 1px solid var(--bs-border-color) !important;
+}
+
.nav-link, .list-group-item {
color: var(--bs-body-color);
}
@@ -100,9 +121,9 @@ svg.logo {
background-image: escape-svg(url("data:image/svg+xml,"));
}
-.nav-link:focus-visible, .nav-item a:focus-visible {
+.nav-item a:focus-visible {
outline: none;
- background-color: var(--pngx-bg-darker);
+ background-color: var(--bs-body-bg);
}
a.navbar-brand:focus-visible {
@@ -335,6 +356,13 @@ textarea,
}
}
+.doc-img-container {
+ border: none !important;
+ border-top-left-radius: .25rem;
+ border-top-right-radius: .25rem;
+ overflow: hidden;
+}
+
// icons
.toolbaricon {
width: 1.2em;
@@ -360,14 +388,6 @@ table.table {
}
}
-.toast {
- color: var(--pngx-primary-text-contrast);
-
- .toast-header {
- color: var(--pngx-primary-text-contrast);
- }
-}
-
.close {
color: var(--bs-body-color);
}
diff --git a/src-ui/src/theme.scss b/src-ui/src/theme.scss
index ea7995be8..a24586879 100644
--- a/src-ui/src/theme.scss
+++ b/src-ui/src/theme.scss
@@ -24,7 +24,7 @@ $text-color-dark-bg-accent: lighten($text-color-dark-bg, 10%);
$form-check-input-checked-bg-image-dark: url("data:image/svg+xml,");
$form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,");
-.text-bg-light {
+.primary-light {
--pngx-primary-text-contrast: #{$text-color-light-bg} !important;
.form-check-input:checked[type=checkbox] {
@@ -36,7 +36,7 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,