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

I'm having trouble with my tablet view taking priority over my desktop view - what could be causing this issue?

Styling for different screen sizes: @media (min-width: 991px) and (max-width:768px){} .container, .container1, .container2 .container3{ float: left; } .container1{ width: 50%; } .container2{ width: 50%; } .container3{ width: 100%; } /**** ...

Exploring the Integration of JSONAPI Included with Angular Observables

Currently, I am in the process of learning how to extract Drupal 8 content into my Angular 7 application using jsonapi. This journey started after reading Preston So's enlightening book on Decoupled Drupal in Practice. However, the guide fell short of ...

Tips for automatically closing one element when another is clicked

My goal is to create a menu that displays when I click on a link, and if another menu is already open, it should close before displaying the new one. Essentially, I want to achieve an accordion menu where only one menu is open at a time. However, despite m ...

Create a new project using Firebase Functions along with a Node.js backend and a React.js frontend

In the process of developing my application, I have chosen to utilize node.js, express.js, and Firebase with firebase functions, all coded in TypeScript. For the client side framework, I am interested in incorporating react.js. Currently, I have set up nod ...

What is the reason for the jQuery plugin not being applied after replacing the page content with an Ajax response?

At the moment, I am utilizing jQuery ajax to dynamically add content to my website. Additionally, I have incorporated the jquery.selectbox-0.6.1.js plugin to enhance the style of select boxes on the page. The plugin successfully styles the select boxes up ...

Padding-left in InfoBox

Currently, I am in the process of developing a map using Google Maps API3 along with the InfoBox extension available at this link I have successfully implemented an overall padding to the Infobox using the following code snippet: var infoOptions = { disa ...

What are the potential drawbacks of utilizing HTML interpolation to modify CSS styles within Angular2+?

My objective was to modify the CSS styling based on whether the user was using a desktop or mobile device. To achieve this, I utilized an observable to determine if the window width exceeded 1000px. Main.ts Component import { Component, OnInit } from &ap ...

What is the best method for efficiently wrapping contents within a div container?

On the website cjshayward.com/index_new.html, there is a div wrapped around the content of the body, which is approximately 1000 pixels wide. In Chrome and Firefox, the wrapper works perfectly for the top section of about 100 pixels. Further down the page, ...

Allow editing for only a specific part of a text box

Creating a customized personal URL page for users on my site is important to me. I envision the value of a text box being "example.com/username," with the "example.com/" part displayed in the text box, but not editable. I've noticed that Tumblr accom ...

Combining angular's CLI project with a groovy Gradle application

I'm in the process of merging the seed project from angular-cli with my Gradle-packaged Java application, deployed on a Tomcat server. How can I successfully combine the Angular build with the Gradle build? Additionally, where is the ideal location t ...

Utilize PrimeNG's async pipe for lazy loading data efficiently

I have a significant amount of data (400,000 records) that I need to display in a PrimeNG data table. In order to prevent browser crashes, I am looking to implement lazy loading functionality for the table which allows the data to be loaded gradually. The ...

Using onDoubleClick with MUI TextField: A Quick Guide

Whenever the user double clicks the input field, I would like to automatically select the text. I have created a function for this specific action: export const selectText = ( event: React.MouseEvent<HTMLInputElement | HTMLTextAreaElement, MouseEvent& ...

Once the page is refreshed, the checkbox should remain in its current state and

I have a challenge with disabling all checkboxes on my page using Angular-Js and JQuery. After clicking on a checkbox, I want to disable all checkboxes but preserve their state after reloading the page. Here is an example of the code snippet: $('# ...

Implement a feature in Bootstrap Vue Timepicker that automatically resets the minutes to 00 whenever the user selects the hours

When a user opens the timepicker, both hours and minutes will be blank. When they choose the hours, the minutes should automatically be set to 00. Thank you for your help. <b-form-timepicker v-model="meditation.start.time" ...

The toggle checkbox feature in AngularJS seems to be malfunctioning as it is constantly stuck in the "off"

I am trying to display the on and off status based on a scope variable. However, it always shows as off, even when it should be on or checked. In the console window, it shows as checked, but on the toggle button it displays as off Here is the HTML code: ...

A guide on incorporating text into a file utilizing JSP within HTML

I am working on a project that includes a JSP file and a .txt file. The JSP file contains a text field and a button, where the user can enter a text and click the button to store it in the .txt file. I have provided my code below, but I seem to be missin ...

Getting rid of the arrow icons in a Material UI TextField

I am facing a challenge with removing the up and down arrow icons from a Material UI TextField that I adjusted using the Material UI documentation (https://material-ui.com/components/autocomplete/#autocomplete) Highlights section. After trying various sol ...

Methods for updating the value of a `<select>` element in an AngularJS controller

Within my HTML code, I have a select element with options ranging from 1 to 10: <select id="selVal" ng-model="product.quantity" ng-options="o as o for o in quantityValues" ng-change="updateDelta(product.quantity, {{product.quantity}}, product.selec ...

Encountering Thumbnail Type Error While Implementing Swiper in Next.js

When trying to integrate Swiper with Next.js, I ran into an issue concerning thumbnails. "onSwiper={setThumbsSwiper}" This line is causing a TypeScript error: swiper-react.d.ts(23, 3): The expected type comes from property 'onSwiper' w ...

Turn off the background color box with a single click

Whenever I click on a header menu item, the background changes along with it. Is there a way to prevent this from happening? https://i.stack.imgur.com/p6bJ9.png Take a look here ...