DEV Community

Cover image for Creating a Dark & Light Toggle Mode in your Angular App 🌚
Muhammad Awais
Muhammad Awais

Posted on • Edited on

4

Creating a Dark & Light Toggle Mode in your Angular App 🌚

Firstly, we have to make the theme-service in our angular app which contains the boolean Subject through which the dark mode is toggled from the components.

What is a Subject?

An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers.

import { Subject } from 'rxjs';
Enter fullscreen mode Exit fullscreen mode

after that, we have to initiate/declare the boolean Subject as pass it to the theme variable with asObservable() so that it can listen the the activity and toggle the theme

private _themeDark: Subject<boolean> = new Subject<boolean>();
isThemeDark = this._themeDark.asObservable();
Enter fullscreen mode Exit fullscreen mode

your theme-service should be like this,

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ThemeService {

  white: string = '#ffffff';
  black: string = '#141313';

  private _themeDark: Subject<boolean> = new Subject<boolean>();

  isThemeDark = this._themeDark.asObservable();

  constructor() { }

  setDarkTheme(isThemeDark: boolean) {
    this._themeDark.next(isThemeDark);

    if (isThemeDark == true) {
      console.log('Dark Used');
      document.documentElement.style.setProperty('--white-color', this.black);
      document.documentElement.style.setProperty('--black-color', this.white);
      localStorage.setItem('dark', 'true');
    }
    else {
      console.log('Light Used');
      document.documentElement.style.setProperty('--white-color', this.white);
      document.documentElement.style.setProperty('--black-color', this.black);
      localStorage.setItem('dark', 'false');
    }
  }

}
Enter fullscreen mode Exit fullscreen mode

And we have to use that service in any component to toggle the app theme.

<!-- sample.component.html -->
<div class="text-right">
  <div class="custom-control custom-switch">
    <mat-checkbox type="checkbox" 
          class="custom-control-input" 
          id="darkMode" 
          [checked]="isThemeDark | async"
          (change)="toggleDarkTheme($event)">
      <label class="custom-control-label" for="darkMode"></label>
      <a class="text-capitalize">Dark Mode</a>
    </mat-checkbox>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Now, in your components .ts file, import the theme-service you have, and import the observable from rxjs

import { ThemeService } from '../../shared/services/theme/theme.service';
import { Observable } from 'rxjs';
Enter fullscreen mode Exit fullscreen mode

And your components .ts file should be like this, which actually contains the toggle handler that will trigger the subject of theme-service observable.

import { Component, OnInit } from '@angular/core';
import { ThemeService } from '../../shared/services/theme/theme.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-sample',
  templateUrl: './sample.component.html',
  styleUrls: ['./sample.component.scss']
})
export class SampleComponent implements OnInit {
  isThemeDark: Observable<boolean>;

  constructor(
    private themeService: ThemeService
  ) {}

  ngOnInit() {
    this.isThemeDark = this.themeService.isThemeDark;
  }

  toggleDarkTheme(checked) {
    this.themeService.setDarkTheme(checked.checked);
    // console.log("checked >", this.isThemeDark);
    console.log("checked >", checked.checked);
  }

}
Enter fullscreen mode Exit fullscreen mode

Github Source

https://gist.github.com/muhammadawaisshaikh/9b62e76a3827a7478c59dc30e0eaa8a1

That's All :)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (2)

Collapse
 
kdipippo profile image
Kathryn DiPippo

Thanks for this tutorial! Worked great!

Collapse
 
thisdotmedia_staff profile image
This Dot Media

Really good to know! Thanks for showing us how to go about this Muhammad 😁

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay