Is it possible to apply a style change to several components at once using a single toggle switch

I am looking to implement a day/night feature on my web app, triggered by a simple toggle click.

While I can easily add this feature to a single component using the navigation menu, I am faced with the challenge of incorporating it into multiple components.

One workaround I came across is utilizing ng-deep, but it doesn't seem like the cleanest solution when modifying the main CSS.

Another approach I considered is creating a service and subscribing to the toggle in each component. However, this method appears to be overly complicated for what I'm trying to achieve.

My main query is: Is there a way to change the style of multiple components with a single toggle switch?

I would prefer not to rely on JavaScript for this task.

Currently, the code snippet from my app.component involves:

import { Component, ElementRef } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})

export class AppComponent {
  title = 'Optimus Engine';
  version = 'Latest';

  day = true;

  constructor(private element: ElementRef) {

  }

  dayNight() {

    if (!this.day) {
      this.element.nativeElement.classList.add('night');
    }

    if (this.day) {
      this.element.nativeElement.classList.remove('night');
    }

    this.day = !this.day;

   //By the way, there seems to be an issue with removing the class, but that's something I need to troubleshoot separately.
  }

}

In the template section:

<div class="toggle-box" (click)="dayNight()">
    <input type="checkbox" name="checkbox1" id="toggle-box-checkbox" />
    <label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
    <label for="toggle-box-checkbox" class="toggle-box-label"></label>
</div>

In the less file:

:host.night h1 {
    transition: all 1s;
        color: aliceblue;
}

However, this styling only applies to h1 elements, and I am exploring ways to extend this functionality to other components based on the same toggle.

Answer №1

To distribute a value across multiple components, you can leverage a service.

Take for example this service:

export class ThemeService {

    private modeSubject: BehaviorSubject<'light'|'dark'> = new BehaviorSubject<'light'|'dark'>('light');

    public get mode():Observable<'light'|'dark'>{
        return this.modeSubject.asObservable();
    }

    public switchMode(newMode:'light'|'dark'):void{
        this.modeSubject.next(newMode);
    }

}

Then, in your component, simply subscribe to the mode observable:

...
...
constructor(themeService: ThemeService){
    themeService.mode.subscribe(mode => this.theme = mode);
}
...
...

finally, use [ngClass] to bind the theme to your template:

Any component that uses this logic will sync with your chosen theme mode (light or dark).

Remember, I used two strings for illustration purposes but you can certainly utilize an enum instead.

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

The placement of the floating element completely messes up the

Whenever I try to float an element in my magnificent popup, the layout gets all messed up. You can see for yourself by trying to put the image and text next to each other using "float: left": http://jsfiddle.net/a7Vj8/1/ Every time I attempt to float th ...

adding content to div is becoming less speedy

Currently, I'm developing a drawing board using only html/css/jquery and the drawing functionality is working smoothly. The approach I've taken involves capturing the mousemove events and placing a dot (div) at each point where the event occurs, ...

Using jQuery to load and parse a JSON file stored on a local system

I am a beginner in scripting languages and recently searched for ways to load and parse JSON files using jQuery. I found helpful resources on Stack Overflow. The JSON file I am working with is called new.json. { "a": [ {"name":"avc"}, ...

What could be causing the Checkbox [checked] to trigger multiple times across all options?

Currently, I am in the process of designing a form that includes a checkbox field allowing for multiple options to be selected. Given that this type of field will be used in various parts of my application, I have decided to implement a directive for thi ...

Utilize JQuery's appendTo() method along with html() function for seamless content replacement

I have a question about appending and replacing div elements. I am currently using the following code: $('.toggle_questions').appendTo('#'+sectionId).show(); While this works perfectly to append my div with the class .toggle_questions ...

Display scrollable content at the bottom

I am currently working on creating a chat application using JavaScript (AngularJS without jQuery) and I am wondering if it is possible to have a scrollable div load to the bottom automatically. While I am familiar with the scrollTo JS property, I do not f ...

Tips for utilizing the form.checkValidity() method in HTML:

While delving into the source code of a website utilizing MVC architecture, I encountered some difficulties comprehending it fully. Here is a snippet of the view's code: function submitForm (action) { var forms = document.getElementById('form& ...

Gridview displaying varying border styles in CSS

I'm really struggling with this issue. I have a GridView and I want to ensure that the borders are consistent across all browsers. Right now, I'm experiencing different outcomes in IE, FF, and Chrome. Despite my best efforts with CSS (I'm re ...

What is the method to choose an invisible link without an identifier using Selenium WebDriver?

I am attempting to click on the link labeled 'User Requested'. This link only appears when hovering over the menu. This is the HTML code: <ul class="k-widget k-reset k-header k-menu k-menu-horizontal" id="menu" data-role="menu" tabindex="0" ...

How come e.target.value always shows the most recent value?

Starting out in HTML and I have a question regarding input. Here is the HTML code I am working with: <input type="text" value="abc" onChange={(e) => { console.log(e.target.value); }}/> I am puzzled because even though the default v ...

What is causing nested divs to generate a scrollbar?

I am struggling with a situation involving 3 layers of nested divs: <div class="outer"> <div class="inner"><div class="item"></div></div> </div> In this scenario, the .inner div is set to position absolute and each d ...

Tips for choosing a subset of objects within a larger array of objects and generating a new array from them?

I am working with an array of 3586 objects, each containing various products. How can I create and store a new array that only includes the products from a specific index? console.log listarPorReferencia() { this.linxService.listarPorReferencia().subs ...

Adding an image to a React component in your project

I am currently working on an app that utilizes React and Typescript. To retrieve data, I am integrating a free API. My goal is to incorporate a default image for objects that lack images. Here is the project structure: https://i.stack.imgur.com/xfIYD.pn ...

What is the best way to position a table caption at the top of a table?

I need help setting up a calendar within a table structure, and I'm struggling to add a caption at the top of the table. Unfortunately, I can't modify the current table structure. I want it to resemble the example shown below: .calendar_wrap ...

The type definition file for '@types' is not present in Ionic's code base

After updating my Ionic 6 project to use Angular 3, everything works perfectly in debug mode. However, when I attempt to compile for production using 'ionic build --prod' or 'ionic cordova build android --prod', I encounter the followin ...

Tips on showcasing a JSON object containing two arrays in HTML using a pair of for loops

I am facing an issue with displaying data from two tables in my PHP script. The personal information is being displayed correctly, but the books related to each person are not showing up. I suspect that my approach might not be efficient enough for handlin ...

"Troubleshooting: IE compatibility issue with jQuery's .each and .children functions

I have created an Instagram image slider feed that works well in Chrome, Safari, Firefox, and Opera. However, it fails to function in all versions of Internet Explorer without showing any error messages. To accurately determine the height of images for th ...

Guide to setting up identically named properties in Child container components

As I am still fairly new to React and its concepts, I may not be executing this correctly. Although the question might seem lengthy, I'll try my best to keep it simple. I have created a component for TableHead that extends some material-ui components ...

New Ways to Style the Final Element in a PHP Array - Part 2

So, here's the current challenge I'm facing along with a detailed explanation of what I'm trying to achieve. Initially, following your suggestions worked smoothly; however, things took a drastic turn when I altered the ORDER BY field and int ...

Positioning Backgrounds with Padding in DIV Elements

I am trying to figure out how to add a check mark next to text in a button with specific styling. I have managed to get the check mark aligned properly using Background:left center, but I also want to add padding and adjust spacing. Is there a way to achie ...