NativeScript/angular

Dark/Lightmode switch breaks on view after a programmatic change of view's background-color

cjohn001 opened this issue · 1 comments

Please do not spent time in analyzing the issue for the moment. I think I found the problem but I need to verify it first. Seems like I have to add .ns-root in CSS before each class definition in order for light/dark mode changes to be reflected. However, I am not sure yet if this is also responsible for the described bug. I will provide an update as soon I were able to check it.

Hello together,
I am currently experiencing a very weird issue when using an attribute directive together with light and darkmode changes.

I have a directive which simulates a touch animation on a GridLayout which serves as a tile :

@Directive({
	selector: '[tileTouchScaleAnimation]'
})
export class TileTouchScaleAnimationDirective {
	private _element: ElementRef;
	private _currentAnimation: any;
	private _baseBackgroundColor: Color;

	//////////////////////////////////////////////////////////////////////////////////////////////////
	constructor(el: ElementRef) {
		this._element = el;
	}
	//////////////////////////////////////////////////////////////////////////////////////////////////
	@HostListener('touch', ['$event'])
	onTouch(args: TouchGestureEventData): void {
		if (args.action === 'down') {
			//	const view = this._element.nativeElement as View;
			//	this._baseBackgroundColor = view.backgroundColor as Color;
			this.animatePressed();
		} else if (args.action === 'up') {
			this.animateReleased();
		}
	}
	//////////////////////////////////////////////////////////////////////////////////////////////////
	private animatePressed(): void {
		if (this._currentAnimation) {
			this._currentAnimation.cancel();
		}
		this._currentAnimation = this._element.nativeElement
			.animate({
				scale: { x: 0.98, y: 0.98 },
				/*
				backgroundColor: new Color(
					235,
					this._baseBackgroundColor.r,
					this._baseBackgroundColor.g,
					this._baseBackgroundColor.b
				),
*/
				curve: CoreTypes.AnimationCurve.easeIn,
				duration: TAP_ACTION_INTERVAL
			})
			.catch((e: any) => {});
	}
	private animateReleased(): void {
		if (this._currentAnimation) {
			this._currentAnimation.cancel();
		}
		this._currentAnimation = this._element.nativeElement
			.animate({
				scale: { x: 1, y: 1 },
				//		backgroundColor: this._baseBackgroundColor,
				curve: CoreTypes.AnimationCurve.easeIn,
				duration: TAP_ACTION_INTERVAL
			})
			.catch((e: any) => {});
	}
}

and I apply this directive to a grid layout simulating a tile:

the css is defined in a _app-common.scss file as:

.tiles-base {
	background-color: $white-bg-trans;
	border-radius: 15;
	border-color: $light-grey-color;
	border-width: 1;
} 
.ns-dark  .tiles-base {
	background-color: $dark-bg-page-trans;
	border-color: $medium-grey-color;
}

Once I have pushed the tile and the animation was run I cannot successfully switch between light and dark mode anymore. Other items on the page still correctly change color, however, the tile on which the animation was run does not change to correct darkmode color or vice versa.

I have different attribute directives simulating button press events in the app. when those animate background-color and than transition to a different page I see problems switching between dark/light mode on items of the opened page.

Has someone an idea what is going wrong here? Help would very much be appreciated.

It seems like once I have set the background-color programmatically (via an attribute directive)
the theme switching does not work anymore.

Workaround

I have not found a workaround yet.

OS: macOS 13.4
CPU: (10) arm64 Apple M1 Pro
Shell: /bin/zsh
node: 18.12.1
npm: 8.19.2
nativescript: 8.5.3

# android
java: 11.0.18
ndk: Not Found
apis: Not Found
build_tools: Not Found
system_images: Not Found

# ios
xcode: 14.3.1/14E300c
cocoapods: 1.12.0
python: 3.11.2
python3: 3.11.2
ruby: 2.7.7
platforms: 
  - DriverKit 22.4
  - iOS 16.4
  - macOS 13.3
  - tvOS 16.4
  - watchOS 9.4

Dependencies

"dependencies": {
  "@angular/animations": "16.0.3",
  "@angular/common": "16.0.3",
  "@angular/compiler": "16.0.3",
  "@angular/core": "16.0.3",
  "@angular/forms": "16.0.3",
  "@angular/platform-browser": "16.0.3",
  "@angular/platform-browser-dynamic": "16.0.3",
  "@angular/router": "16.0.3",
  "@apollo/client": "3.7.14",
  "@mnd/external-web-view": "file:../mnd-plugins/dist/packages/external-web-view/mnd-external-web-view-1.0.0.tgz",
  "@nativescript/angular": "16.0.0",
  "@nativescript/core": "8.5.3",
  "@nativescript/iqkeyboardmanager": "2.1.1",
  "@nativescript/localize": "5.1.0",
  "@nativescript/mlkit-barcode-scanning": "2.0.0",
  "@nativescript/mlkit-core": "2.0.0",
  "@nativescript/secure-storage": "3.0.0",
  "@nativescript/theme": "3.0.2",
  "@nativescript/ui-charts": "0.2.4",
  "apollo-angular": "5.0.0",
  "apollo3-cache-persist": "0.14.1",
  "d3-ease": "3.0.1",
  "graphql": "16.6.0",
  "graphql-tag": "2.12.6",
  "intl": "1.2.5",
  "moment": "2.29.4",
  "nativescript-health-data": "file:../mnd-custom-plugins/nativescript-health-data/publish/package/nativescript-health-data-2.0.0.tgz",
  "nativescript-oauth2-ext": "file:../mnd-custom-plugins/nativescript-oauth2-ext/publish/package/nativescript-oauth2-ext-3.0.1.tgz",
  "nativescript-sqlite": "2.8.6",
  "nativescript-ui-calendar": "15.2.3",
  "nativescript-ui-gauge": "15.2.3",
  "rxjs": "7.8.1",
  "uuid": "9.0.0",
  "zone.js": "0.13.0"
},
"devDependencies": {
  "@angular-devkit/build-angular": "16.0.3",
  "@angular/compiler-cli": "16.0.3",
  "@graphql-codegen/cli": "4.0.0",
  "@graphql-codegen/fragment-matcher": "5.0.0",
  "@graphql-codegen/introspection": "4.0.0",
  "@graphql-codegen/typescript": "4.0.0",
  "@graphql-codegen/typescript-apollo-angular": "3.5.6",
  "@graphql-codegen/typescript-operations": "4.0.0",
  "@nativescript/android": "8.5.0",
  "@nativescript/ios": "8.5.2",
  "@nativescript/types": "8.5.0",
  "@nativescript/webpack": "5.0.14",
  "@ngtools/webpack": "16.0.3",
  "@types/d3-ease": "3.0.0",
  "@types/intl": "1.2.0",
  "@types/node": "20.2.5",
  "@types/uuid": "9.0.1",
  "keycloak-request-token": "0.1.0",
  "rimraf": "5.0.1",
  "sass": "1.62.1",
  "ts-node": "10.9.1",
  "typescript": "4.9.5"
}

I close the issue as the bug was in my code. In order to get CSS class switching working every class has to be below .ns-root

for example:

.ns-root .high-contrast-label {
color: $dark-grey-text-color;
}
.ns-root.ns-dark .high-contrast-label {
color: $very-light-grey-color;
}

If NS Angular is used and component scss is used in addition :host is required

.ns-root :host .high-contrast-label {
color: $dark-grey-text-color;
}
.ns-root.ns-dark :host .high-contrast-label {
color: $very-light-grey-color;
}

Would be helpful to have this information in the docs.