mirror of
https://github.com/apache/nifi.git
synced 2025-02-07 10:38:33 +00:00
[NIFI-12727] Detect theme based on OS setting, allow user override (#8352)
* [NIFI-12727] Detect theme based on OS setting, allow user override * update storage service types, introduce theming service for user selection of theme settings * review feedback, update menu option disaplay names, update storage service types, delete expired local storage items on init * check for existence of window.matchmedia * rebase and address review comments This closes #8352
This commit is contained in:
parent
72f6d8a680
commit
f39f3ea252
@ -15,9 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { GuardsCheckEnd, GuardsCheckStart, NavigationCancel, Router } from '@angular/router';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { Storage } from './service/storage.service';
|
||||
import { ThemingService } from './service/theming.service';
|
||||
|
||||
@Component({
|
||||
selector: 'nifi',
|
||||
@ -28,7 +30,11 @@ export class AppComponent {
|
||||
title = 'nifi';
|
||||
guardLoading = true;
|
||||
|
||||
constructor(private router: Router) {
|
||||
constructor(
|
||||
private router: Router,
|
||||
private storage: Storage,
|
||||
private themingService: ThemingService
|
||||
) {
|
||||
this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {
|
||||
if (event instanceof GuardsCheckStart) {
|
||||
this.guardLoading = true;
|
||||
@ -37,5 +43,21 @@ export class AppComponent {
|
||||
this.guardLoading = false;
|
||||
}
|
||||
});
|
||||
|
||||
let theme = this.storage.getItem('theme');
|
||||
|
||||
// Initially check if dark mode is enabled on system
|
||||
const darkModeOn = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
// If dark mode is enabled then directly switch to the dark-theme
|
||||
this.themingService.toggleTheme(darkModeOn, theme);
|
||||
|
||||
if (window.matchMedia) {
|
||||
// Watch for changes of the preference
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
|
||||
theme = this.storage.getItem('theme');
|
||||
this.themingService.toggleTheme(e.matches, theme);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ import { CanvasState } from '../index';
|
||||
import { CanvasView } from '../../service/canvas-view.service';
|
||||
import { BirdseyeView } from '../../service/birdseye-view.service';
|
||||
|
||||
interface StorageTransform {
|
||||
scale: number;
|
||||
translateX: number;
|
||||
translateY: number;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TransformEffects {
|
||||
private static readonly VIEW_PREFIX: string = 'nifi-view-';
|
||||
@ -48,7 +54,7 @@ export class TransformEffects {
|
||||
const name: string = TransformEffects.VIEW_PREFIX + processGroupId;
|
||||
|
||||
// create the item to store
|
||||
const item = {
|
||||
const item: StorageTransform = {
|
||||
scale: transform.scale,
|
||||
translateX: transform.translate.x,
|
||||
translateY: transform.translate.y
|
||||
@ -70,7 +76,7 @@ export class TransformEffects {
|
||||
try {
|
||||
// see if we can restore the view position from storage
|
||||
const name: string = TransformEffects.VIEW_PREFIX + processGroupId;
|
||||
const item = this.storage.getItem(name);
|
||||
const item: StorageTransform | null = this.storage.getItem(name);
|
||||
|
||||
// ensure the item is valid
|
||||
if (item) {
|
||||
|
@ -47,7 +47,9 @@ export class NavigationControl {
|
||||
private storage: Storage
|
||||
) {
|
||||
try {
|
||||
const item = this.storage.getItem(NavigationControl.CONTROL_VISIBILITY_KEY);
|
||||
const item: { [key: string]: boolean } | null = this.storage.getItem(
|
||||
NavigationControl.CONTROL_VISIBILITY_KEY
|
||||
);
|
||||
if (item) {
|
||||
this.navigationCollapsed = item[NavigationControl.NAVIGATION_KEY] === false;
|
||||
this.store.dispatch(setNavigationCollapsed({ navigationCollapsed: this.navigationCollapsed }));
|
||||
@ -62,7 +64,7 @@ export class NavigationControl {
|
||||
this.store.dispatch(setNavigationCollapsed({ navigationCollapsed: this.navigationCollapsed }));
|
||||
|
||||
// update the current value in storage
|
||||
let item = this.storage.getItem(NavigationControl.CONTROL_VISIBILITY_KEY);
|
||||
let item: { [key: string]: boolean } | null = this.storage.getItem(NavigationControl.CONTROL_VISIBILITY_KEY);
|
||||
if (item == null) {
|
||||
item = {};
|
||||
}
|
||||
|
@ -65,7 +65,9 @@ export class OperationControl {
|
||||
private storage: Storage
|
||||
) {
|
||||
try {
|
||||
const item = this.storage.getItem(OperationControl.CONTROL_VISIBILITY_KEY);
|
||||
const item: { [key: string]: boolean } | null = this.storage.getItem(
|
||||
OperationControl.CONTROL_VISIBILITY_KEY
|
||||
);
|
||||
if (item) {
|
||||
this.operationCollapsed = item[OperationControl.OPERATION_KEY] === false;
|
||||
this.store.dispatch(setOperationCollapsed({ operationCollapsed: this.operationCollapsed }));
|
||||
@ -80,7 +82,7 @@ export class OperationControl {
|
||||
this.store.dispatch(setOperationCollapsed({ operationCollapsed: this.operationCollapsed }));
|
||||
|
||||
// update the current value in storage
|
||||
let item = this.storage.getItem(OperationControl.CONTROL_VISIBILITY_KEY);
|
||||
let item: { [key: string]: boolean } | null = this.storage.getItem(OperationControl.CONTROL_VISIBILITY_KEY);
|
||||
if (item == null) {
|
||||
item = {};
|
||||
}
|
||||
|
@ -17,6 +17,11 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
interface StorageEntry<T> {
|
||||
expires: number;
|
||||
item: T;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
@ -24,13 +29,29 @@ export class Storage {
|
||||
private static readonly MILLIS_PER_DAY: number = 86400000;
|
||||
private static readonly TWO_DAYS: number = Storage.MILLIS_PER_DAY * 2;
|
||||
|
||||
constructor() {
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
try {
|
||||
// get the next item
|
||||
const key: string | null = localStorage.key(i);
|
||||
|
||||
if (key) {
|
||||
// attempt to get the item which will expire if necessary
|
||||
this.getItem(key);
|
||||
}
|
||||
} catch (e) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the expiration for the specified entry.
|
||||
*
|
||||
* @param {object} entry
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private checkExpiration(entry: any): boolean {
|
||||
private checkExpiration<T>(entry: StorageEntry<T>): boolean {
|
||||
if (entry.expires) {
|
||||
// get the expiration
|
||||
const expires: Date = new Date(entry.expires);
|
||||
@ -48,10 +69,10 @@ export class Storage {
|
||||
*
|
||||
* @param {string} key
|
||||
*/
|
||||
private getEntry(key: string): null | any {
|
||||
private getEntry<T>(key: string): null | StorageEntry<T> {
|
||||
try {
|
||||
// parse the entry
|
||||
const item: any | null = localStorage.getItem(key);
|
||||
const item = localStorage.getItem(key);
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
@ -76,12 +97,12 @@ export class Storage {
|
||||
* @param {object} item
|
||||
* @param {number} expires
|
||||
*/
|
||||
public setItem(key: string, item: any, expires?: number): void {
|
||||
public setItem<T>(key: string, item: T, expires?: number): void {
|
||||
// calculate the expiration
|
||||
expires = expires != null ? expires : new Date().valueOf() + Storage.TWO_DAYS;
|
||||
|
||||
// create the entry
|
||||
const entry = {
|
||||
const entry: StorageEntry<T> = {
|
||||
expires,
|
||||
item
|
||||
};
|
||||
@ -108,8 +129,8 @@ export class Storage {
|
||||
*
|
||||
* @param {type} key
|
||||
*/
|
||||
public getItem(key: string): null | any {
|
||||
const entry = this.getEntry(key);
|
||||
public getItem<T>(key: string): null | T {
|
||||
const entry: StorageEntry<T> | null = this.getEntry(key);
|
||||
if (entry === null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
|
||||
export const DARK_THEME = 'DARK_THEME';
|
||||
export const LIGHT_THEME = 'LIGHT_THEME';
|
||||
export const OS_SETTING = 'OS_SETTING';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ThemingService {
|
||||
constructor(@Inject(DOCUMENT) private _document: Document) {}
|
||||
|
||||
toggleTheme(darkModeOn: boolean, theme: any) {
|
||||
if (darkModeOn) {
|
||||
if (theme === DARK_THEME) {
|
||||
this._document.body.classList.toggle('dark-theme', true);
|
||||
} else if (theme === LIGHT_THEME) {
|
||||
this._document.body.classList.toggle('dark-theme', false);
|
||||
} else {
|
||||
this._document.body.classList.toggle('dark-theme', true);
|
||||
}
|
||||
} else {
|
||||
if (theme === DARK_THEME) {
|
||||
this._document.body.classList.toggle('dark-theme', true);
|
||||
} else if (theme === LIGHT_THEME) {
|
||||
this._document.body.classList.toggle('dark-theme', false);
|
||||
} else {
|
||||
this._document.body.classList.toggle('dark-theme', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -30,7 +30,6 @@
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<div class="flex justify-between items-center gap-x-1" *ngIf="currentUser$ | async as user">
|
||||
<mat-slide-toggle color="primary" (click)="toggleTheme()"></mat-slide-toggle>
|
||||
<div class="flex flex-col justify-between items-end gap-y-1">
|
||||
<div class="current-user">{{ user.identity }}</div>
|
||||
<a href="#" *ngIf="allowLogin(user)">log in</a>
|
||||
@ -140,6 +139,24 @@
|
||||
<i class="fa fa-fw fa-info-circle mr-2"></i>
|
||||
About
|
||||
</button>
|
||||
<button mat-menu-item [matMenuTriggerFor]="theming">Appearance</button>
|
||||
</mat-menu>
|
||||
<mat-menu #theming="matMenu" xPosition="before">
|
||||
<button mat-menu-item class="global-menu-item" (click)="toggleTheme(LIGHT_THEME)">
|
||||
<i class="fa fa-fw fa-check mr-2" *ngIf="theme === LIGHT_THEME"></i>
|
||||
<i class="fa fa-fw mr-2" *ngIf="theme !== LIGHT_THEME"></i>
|
||||
Light
|
||||
</button>
|
||||
<button mat-menu-item class="global-menu-item" (click)="toggleTheme(DARK_THEME)">
|
||||
<i class="fa fa-fw fa-check mr-2" *ngIf="theme === DARK_THEME"></i>
|
||||
<i class="fa fa-fw mr-2" *ngIf="theme !== DARK_THEME"></i>
|
||||
Dark
|
||||
</button>
|
||||
<button mat-menu-item class="global-menu-item" (click)="toggleTheme(OS_SETTING)">
|
||||
<i class="fa fa-fw fa-check mr-2" *ngIf="theme === OS_SETTING || theme === null"></i>
|
||||
<i class="fa fa-fw mr-2" *ngIf="theme !== OS_SETTING && theme !== null"></i>
|
||||
Device
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { AsyncPipe, DOCUMENT, NgIf, NgOptimizedImage } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
import { AsyncPipe, NgIf, NgOptimizedImage } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
@ -31,12 +31,14 @@ import { selectCurrentUser } from '../../../state/current-user/current-user.sele
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { NiFiState } from '../../../state';
|
||||
import { selectFlowConfiguration } from '../../../state/flow-configuration/flow-configuration.selectors';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { Storage } from '../../../service/storage.service';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { OS_SETTING, LIGHT_THEME, DARK_THEME, ThemingService } from '../../../service/theming.service';
|
||||
|
||||
@Component({
|
||||
selector: 'navigation',
|
||||
standalone: true,
|
||||
providers: [Storage],
|
||||
imports: [
|
||||
NgOptimizedImage,
|
||||
AsyncPipe,
|
||||
@ -45,24 +47,39 @@ import { Storage } from '../../../service/storage.service';
|
||||
NgIf,
|
||||
RouterLink,
|
||||
MatButtonModule,
|
||||
MatSlideToggleModule,
|
||||
FormsModule
|
||||
FormsModule,
|
||||
MatCheckboxModule
|
||||
],
|
||||
templateUrl: './navigation.component.html',
|
||||
styleUrls: ['./navigation.component.scss']
|
||||
})
|
||||
export class Navigation {
|
||||
theme: any | undefined;
|
||||
darkModeOn: boolean | undefined;
|
||||
LIGHT_THEME: string = LIGHT_THEME;
|
||||
DARK_THEME: string = DARK_THEME;
|
||||
OS_SETTING: string = OS_SETTING;
|
||||
currentUser$ = this.store.select(selectCurrentUser);
|
||||
flowConfiguration$ = this.store.select(selectFlowConfiguration);
|
||||
isDarkMode = false;
|
||||
|
||||
constructor(
|
||||
private store: Store<NiFiState>,
|
||||
private authStorage: AuthStorage,
|
||||
private authService: AuthService,
|
||||
private storage: Storage,
|
||||
@Inject(DOCUMENT) private _document: Document
|
||||
) {}
|
||||
private themingService: ThemingService
|
||||
) {
|
||||
this.darkModeOn = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
this.theme = this.storage.getItem('theme');
|
||||
|
||||
if (window.matchMedia) {
|
||||
// Watch for changes of the preference
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
|
||||
this.darkModeOn = e.matches;
|
||||
this.theme = this.storage.getItem('theme');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
allowLogin(user: CurrentUser): boolean {
|
||||
return user.anonymous && location.protocol === 'https:';
|
||||
@ -97,14 +114,13 @@ export class Navigation {
|
||||
}
|
||||
|
||||
getCanvasLink(): string {
|
||||
const canvasRoute = this.storage.getItem('current-canvas-route');
|
||||
const canvasRoute = this.storage.getItem<string>('current-canvas-route');
|
||||
return canvasRoute || '/';
|
||||
}
|
||||
|
||||
toggleTheme(value = !this.isDarkMode) {
|
||||
this.isDarkMode = value;
|
||||
this._document.body.classList.toggle('dark-theme', value);
|
||||
|
||||
// TODO: save to local storage or read OS settings???
|
||||
toggleTheme(theme: string) {
|
||||
this.theme = theme;
|
||||
this.storage.setItem('theme', theme);
|
||||
this.themingService.toggleTheme(!!this.darkModeOn, theme);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
// Custom Colors following Material Design
|
||||
// For more information: https://m2.material.io/design/color/the-color-system.html
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
// The $material-primary-light-palette define the PRIMARY AND ACCENT palettes for all Angular Material components used throughout Apache NiFi
|
||||
$material-primary-light-palette: (
|
||||
@ -390,3 +391,66 @@ $warn-dark-palette: (
|
||||
A700: rgba(black, 0.87),
|
||||
)
|
||||
);
|
||||
|
||||
// Define the palettes for your theme
|
||||
$material-primary-light: mat.define-palette($material-primary-light-palette);
|
||||
$material-accent-light: mat.define-palette($material-primary-light-palette, A400, A100, A700);
|
||||
$nifi-canvas-primary-light: mat.define-palette($nifi-canvas-light-palette);
|
||||
$nifi-canvas-accent-light: mat.define-palette($nifi-canvas-accent-light-palette, 400, 100, 700);
|
||||
$warn-light: mat.define-palette($warn-light-palette, 400, 100, 700);
|
||||
|
||||
// Create the theme objects. We can extract the values we need from the theme passed into the mixins.
|
||||
$material-theme-light: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $material-primary-light,
|
||||
accent: $material-accent-light,
|
||||
warn: $warn-light
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
$nifi-canvas-theme-light: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $nifi-canvas-primary-light,
|
||||
accent: $nifi-canvas-accent-light,
|
||||
warn: $warn-light
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
// Create the color palettes used in our dark theme.
|
||||
$material-primary-dark: mat.define-palette($material-primary-dark-palette);
|
||||
$material-accent-dark: mat.define-palette($material-primary-dark-palette, A400, A100, A700);
|
||||
$nifi-canvas-primary-dark: mat.define-palette($nifi-canvas-dark-palette);
|
||||
$nifi-canvas-accent-dark: mat.define-palette($nifi-canvas-accent-dark-palette);
|
||||
$warn-dark: mat.define-palette($warn-dark-palette, 600, 200, 800);
|
||||
|
||||
$material-theme-dark: mat.define-dark-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $material-primary-dark,
|
||||
accent: $material-accent-dark,
|
||||
warn: $warn-dark
|
||||
),
|
||||
density: 0,
|
||||
typography: mat.define-typography-config(),
|
||||
)
|
||||
);
|
||||
|
||||
$nifi-canvas-theme-dark: mat.define-dark-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $nifi-canvas-primary-dark,
|
||||
accent: $nifi-canvas-accent-dark,
|
||||
warn: $warn-dark,
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
@ -391,3 +391,67 @@ $warn-dark-palette: (
|
||||
A700: rgba(black, 0.87),
|
||||
)
|
||||
);
|
||||
|
||||
// Define the palettes for your theme
|
||||
$material-primary-light: mat.define-palette($material-primary-light-palette);
|
||||
$material-accent-light: mat.define-palette($material-primary-light-palette, A400, A100, A700);
|
||||
$nifi-canvas-primary-light: mat.define-palette($nifi-canvas-light-palette);
|
||||
$nifi-canvas-accent-light: mat.define-palette($nifi-canvas-accent-light-palette, 400, 100, 700);
|
||||
$warn-light: mat.define-palette($warn-light-palette, 400, 100, 700);
|
||||
|
||||
// Create the theme objects. We can extract the values we need from the theme passed into the mixins.
|
||||
$material-theme-light: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $material-primary-light,
|
||||
accent: $material-accent-light,
|
||||
warn: $warn-light
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
$nifi-canvas-theme-light: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $nifi-canvas-primary-light,
|
||||
accent: $nifi-canvas-accent-light,
|
||||
warn: $warn-light
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
// Create the color palettes used in our dark theme.
|
||||
$material-primary-dark: mat.define-palette($material-primary-dark-palette);
|
||||
$material-accent-dark: mat.define-palette($material-primary-dark-palette, A400, A100, A700);
|
||||
$nifi-canvas-primary-dark: mat.define-palette($nifi-canvas-dark-palette);
|
||||
$nifi-canvas-accent-dark: mat.define-palette($nifi-canvas-accent-dark-palette);
|
||||
$warn-dark: mat.define-palette($warn-dark-palette, 600, 200, 800);
|
||||
|
||||
$material-theme-dark: mat.define-dark-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $material-primary-dark,
|
||||
accent: $material-accent-dark,
|
||||
warn: $warn-dark
|
||||
),
|
||||
density: 0,
|
||||
typography: mat.define-typography-config(),
|
||||
)
|
||||
);
|
||||
|
||||
$nifi-canvas-theme-dark: mat.define-dark-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $nifi-canvas-primary-dark,
|
||||
accent: $nifi-canvas-accent-dark,
|
||||
warn: $warn-dark,
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -456,38 +456,6 @@ $appFontPath: '~roboto-fontface/fonts';
|
||||
}
|
||||
}
|
||||
|
||||
// Define the palettes for your theme
|
||||
$material-primary-light: mat.define-palette($material-primary-light-palette);
|
||||
$material-accent-light: mat.define-palette($material-primary-light-palette, A400, A100, A700);
|
||||
$nifi-canvas-primary-light: mat.define-palette($nifi-canvas-light-palette);
|
||||
$nifi-canvas-accent-light: mat.define-palette($nifi-canvas-accent-light-palette, 400, 100, 700);
|
||||
$warn-light: mat.define-palette($warn-light-palette, 400, 100, 700);
|
||||
|
||||
// Create the theme objects. We can extract the values we need from the theme passed into the mixins.
|
||||
$material-theme-light: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $material-primary-light,
|
||||
accent: $material-accent-light,
|
||||
warn: $warn-light
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
$nifi-canvas-theme-light: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $nifi-canvas-primary-light,
|
||||
accent: $nifi-canvas-accent-light,
|
||||
warn: $warn-light
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
// only include this once (not needed for dark mode)
|
||||
@include nifi-styles();
|
||||
|
||||
@ -538,37 +506,6 @@ $nifi-canvas-theme-light: mat.define-light-theme(
|
||||
@include provenance-event-dialog.nifi-theme($material-theme-light);
|
||||
|
||||
.dark-theme {
|
||||
// Create the color palettes used in our dark theme.
|
||||
$material-primary-dark: mat.define-palette($material-primary-dark-palette);
|
||||
$material-accent-dark: mat.define-palette($material-primary-dark-palette, A400, A100, A700);
|
||||
$nifi-canvas-primary-dark: mat.define-palette($nifi-canvas-dark-palette);
|
||||
$nifi-canvas-accent-dark: mat.define-palette($nifi-canvas-accent-dark-palette);
|
||||
$warn-dark: mat.define-palette($warn-dark-palette, 600, 200, 800);
|
||||
|
||||
$material-theme-dark: mat.define-dark-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $material-primary-dark,
|
||||
accent: $material-accent-dark,
|
||||
warn: $warn-dark
|
||||
),
|
||||
density: 0,
|
||||
typography: mat.define-typography-config(),
|
||||
)
|
||||
);
|
||||
|
||||
$nifi-canvas-theme-dark: mat.define-dark-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $nifi-canvas-primary-dark,
|
||||
accent: $nifi-canvas-accent-dark,
|
||||
warn: $warn-dark,
|
||||
),
|
||||
//typography: mat.define-typography-config(), // TODO: typography
|
||||
density: -3
|
||||
)
|
||||
);
|
||||
|
||||
// Include the dark theme color styles.
|
||||
@include mat.all-component-colors($material-theme-dark);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user