What steps can I take to ensure that Angular component animations are triggered by changes to CSS classes, instead of relying on static

I've developed a unique block-cursor date/time input field that utilizes Angular states and animations to showcase various ongoing or transitional states. These input fields are live on this website:

export const BACKGROUND_ANIMATIONS = trigger('displayState', [
  state('error',     style({ backgroundColor: getBackgroundColor(ERROR_BACKGROUND, '#F67') })),
  state('normal',    style({ backgroundColor: getBackgroundColor(NORMAL_BACKGROUND, 'white') })),
  state('confirm',   style({ backgroundColor: getBackgroundColor(CONFIRM_BACKGROUND, '#6C6') })),
  state('warning',   style({ backgroundColor: getBackgroundColor(WARNING_BACKGROUND, '#FC6') })),
  state('view-only', style({ backgroundColor: getBackgroundColor(VIEW_ONLY_BACKGROUND, 'black') })),
  state('disabled',  style({ backgroundColor: getBackgroundColor(DISABLED_BACKGROUND, '#CCC') })),
  state('dark-error',     style({ backgroundColor: getBackgroundColor(ERROR_BACKGROUND, '#C36', true) })),
  state('dark-normal',    style({ backgroundColor: getBackgroundColor(NORMAL_BACKGROUND, '#333', true) })),
  state('dark-confirm',   style({ backgroundColor: getBackgroundColor(CONFIRM_BACKGROUND, '#292', true) })),
  state('dark-warning',   style({ backgroundColor: getBackgroundColor(WARNING_BACKGROUND, '#B80', true) })),
  state('dark-view-only', style({ backgroundColor: getBackgroundColor(VIEW_ONLY_BACKGROUND, '#0A0', true) })),
  state('dark-disabled',  style({ backgroundColor: getBackgroundColor(DISABLED_BACKGROUND, '#444', true) })),
  transition('normal => error',   animate(FLASH_DURATION)),
  transition('error => normal',   animate(FLASH_DURATION)),
  transition('normal => confirm', animate(FLASH_DURATION)),
  transition('confirm => normal', animate(FLASH_DURATION)),
  transition('warning => error',  animate(FLASH_DURATION)),
  transition('error => warning',  animate(FLASH_DURATION)),
  transition('dark-normal => dark-error',   animate(FLASH_DURATION)),
  transition('dark-error => dark-normal',   animate(FLASH_DURATION)),
  transition('dark-normal => dark-confirm', animate(FLASH_DURATION)),
  transition('dark-confirm => dark-normal', animate(FLASH_DURATION)),
  transition('dark-warning => dark-error',  animate(FLASH_DURATION)),
  transition('dark-error => dark-warning',  animate(FLASH_DURATION))
]);

All the above animations are defined within an abstract superclass for flexible usage in concrete subclasses:

@Component({
  selector: 'tbw-time-editor',
  animations: [BACKGROUND_ANIMATIONS],
  templateUrl: '../digit-sequence-editor/digit-sequence-editor.directive.html',
  styleUrls: ['../digit-sequence-editor/digit-sequence-editor.directive.scss', './time-editor.component.scss'],
  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimeEditorComponent), multi: true },
              { provide: NG_VALIDATORS, useExisting: forwardRef(() => TimeEditorComponent), multi: true }]
})
export class TimeEditorComponent extends DigitSequenceEditorDirective<number> implements OnInit {
  ...

My goal is to reduce the number of display states by half and eliminate the need for prefixed dark_ states. Ideally, I want color updates to be automatic based on the addition of the tbw-dark-mode class to the HTML body.

Presently, my design is limited to supporting only light and dark modes with customization options. Creating additional modes beyond these two presets seems unfeasible at the moment.

An issue arises with timing as the color definitions are generated during application initialization, lacking a way to update them later using Angular APIs.

The function getBackgroundColor() helps initially define colors, but it's not without flaws such as iOS Safari misinterpreting transparency leading to fixed fallback values.

Though I devised a workaround for dynamic color updates, using a custom DynamicColor class enforced type coercion and screen refreshing to implement changes.

Is there a more efficient method? Perhaps leveraging CSS classes instead of predefined styles or uncovering an undiscovered Angular API to alter animations installed by the @Component decorator?

Answer №1

Have you considered using CSS variables to define colors?

https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

You have the flexibility to easily switch between different color schemes by changing variables like --color-1 to --color-2 in your animations.

In another section of your project, modifying these variable definitions can be done with code similar to this:

@Component({ /*…*/ })
export class MyComponent {
  @HostBinding("style.--color-1")
  private color1: string;

  changeColor1(value: string) {
   this.color1 = value;
  }
}

Please note: CSS variable support is robust unless compatibility with Internet Explorer is required: https://caniuse.com/css-variables

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can someone help me figure out this lengthy React error coming from Material UI?

Issues encountered:X ERROR in ./src/Pages/Crypto_transactions.js 184:35-43 The export 'default' (imported as 'DataGrid') could not be found in '@material-ui/data-grid' (potential exports include: DATA_GRID_PROPTYPES, DEFAULT ...

I can't seem to figure out why I continue to receive the error message stating that 'app.get is not a function'

Below is the code I am currently using: const request = require('request'); const app = require('express'); app.get('/', function (req, res) { res.send('hello world'); }); app.listen(3000); Unfortunately, I keep e ...

When using the if-else statement to check the typeof value, it is returning as undefined

update Hello, I conducted a test on your code and found that it breaks for another scenario when the mobileVersion is set as sample.pdf. In this case, I am getting skyCloudmageProfilePic as pdfProfilePic without removing the typeof condition. Here is the ...

How to successfully integrate the three.js example of webgl_loader_obj_mtl.html into an ASP.NET WebForm, even when encountering issues with mtlLoader.setPath

While attempting to integrate the webgl_loader_obj_mtl.html example from three.js into an ASP.NET WebForm, I encountered an issue. Upon running the HTML, Visual Studio 2015 failed at mtlLoader.setPath. Has anyone else experienced the same problem? Addition ...

Converting CommonJS default exports into named exports / Unable to load ES module

I've encountered an issue while creating a Discord bot with discord.js using TypeScript. When attempting to run the resulting JavaScript code, I'm facing an error that states: import { Client, FriendlyError, SQLiteProvider } from 'discord.js ...

Is it a never-ending cycle of subscriptions within a subscription?

I am currently facing a challenge with using multiples/forEach subscribe inside another subscribe. My goal is to retrieve a list of objects and then fetch their images based on their ID. The code I have written so far looks like this: this.appTypeService. ...

The name 'require' could not be located

Currently, I'm attempting to integrate angular2-highcharts into an Angular CLI application. When configuring the app module as shown below, import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-b ...

"Mesmerizing Motion: The World of Three

Exploring the world of ThreeJS, I am experimenting with the concept of incorporating multiple objects in a scene and implementing transitions on these objects with the click of a button. While I have grasped the idea of working with multiple objects and a ...

Remove the array stored in the local storage of an Ionic 2 application

In my application, I store data in a string. To convert the data into arrays, I use JSON.parse. this.items = JSON.parse(todos); On the results page, I display my arrays as follows: Array1 Array2 Array3 However, I have noticed that the delete button aft ...

The field 'name' is not recognized on type 'never'

Currently immersing myself in Angular and experimenting with making an API call, but I'm encountering the following error: error TS2339: Property 'name' does not exist on type 'never'. import { Component, OnInit } from '@angu ...

Guide to generating interactive material-ui components within a react application?

I am facing a challenge in creating a dynamic mui grid element triggered by a button click in a React component. When attempting to create let newGrid = document.createElement('Grid'), it does not behave the same way as a regular div creation. D ...

Firefox's keyup event

Is it possible to detect a keypress using the jQuery keyup function, as I am facing an issue where it works in Chrome, Edge, IE, and Opera but not in Firefox. $(".textfield").contents().keyup(function(evnt) { document.getElementById("btn_save").style. ...

Tips for incorporating a favicon in a React application

Having trouble adding a favicon to my React application. I followed the instructions in this post, but it's not working for me. I placed the favicon.ico file inside the public folder where index.html resides. This is how my directory structure looks ...

choose a selection hopscotch

Is there a way to prevent the input field from jumping out of alignment when an option is selected in these q-select inputs? I want to fix this issue so that the field remains in line with the horizontal alignment. https://codepen.io/kiggs1881/pen/RwENYEX ...

What is the best way to include a post identifier in my ajax request?

Currently, I am looking to enhance my ajax functionality by including a post identifier. At the moment, I identify my posts by checking for the presence of a specific input field. Below is the snippet of code that illustrates this: <input name="id" id= ...

"Surprising quirks in the functionality of Bootstrap's image gallery

My goal is to create a matrix layout of 30 group member photos using HTML, CSS, and Bootstrap. Unfortunately, some of the photos are not aligning properly and are appearing in the wrong block, leaving some blocks empty. All the photos have the same aspect ...

Gather data from various HTML elements with JavaScript when submitting a form

How can I extract values from HTML elements and send them for processing through a form? I'm attempting to compile a menu item list with the individual items' structure in place, but I'm struggling to figure out how to fetch the values upon ...

Include a pop-up with an image within a table - Shiny

I have a situation where I need to display images and metrics in a compact table. The challenge is to show the images in a small size within the table, but allow users to hover over them for a larger view using a popover feature. While I managed to resize ...

Utilizing AngularJS and CSS selectors for effective form validation

Just a quick question: Can someone explain why the summary class is able to be directly added to the <span> element, but not the ng-classes onto the <form> tag? Could it be because the ng-classes are dynamically generated at runtime? What rul ...

Mysql Node Challenge

Upon running the following code, I encountered a MYSQL error. After carefully reviewing the syntax, everything appears to be correct. However, I am unsure why this error is being thrown. app.post('/:roomname/create',function(request, response){ ...