Implementing a Material Angular Theme Switching Component

jesserules

jesserules

Posted on June 12, 2023

Implementing a Material Angular Theme Switching Component

Angular 16 Theme Switching

A quick knowledge drop on implementing theming

Below is what the final outcome is and the end goal of this walkthrough.

Since I am not trying to sling more ads than a recipe website here's the Git Repo upfront: Git Repo

Theme Selector

You can see on this website, my photography website, that you can switch out themes by clicking the icon at the top.

In Practice

First I created the app with the angular cli: ng new ThemePicker.

I left the default to build it with css files instead of scss files to show how to migrate this.

This is a common scenario I have ran into, where old apps are written with css files instead of using scss. So, let's fix this.

create New with css

To fix this flub of css instead of scss we are going to use a handy npm package Scss Migrate: SCSS Migrate Git

installmigrationnpm

Once you have this installed you can run the command:

ng g schematics-scss-migrate:scss-migrate
Enter fullscreen mode Exit fullscreen mode

The command from above will have you select the "from" and the "to." In our case this is "CSS" to "SCSS"

migrate to scss step 1

But make sure you run it from the parent of the /src file or it will only swap out styles.css to styles.scss.

Running it from the parent of /src updates all the component modules as well.

Run the script and select CSS to Scss for steps 1 & 2

migrate to scss step 2

The third step will ask you for your app's name, you can find this in the angular.json file:

App Name

That's it! We are now switched over to scss.

migrate to scss

Make sure your angluar.json was updated with the scss schematics:

            "projectType": "application",
            "schematics": {
                "@schematics/angular:application": {
                    "strict": true
                },
                "@schematics/angular:component": {
                    "style": "scss"
                }
            },
Enter fullscreen mode Exit fullscreen mode

Angular Json updated

Let's get to theming!

First, let's use an awesome NPM package to do this AngularMaterialCSSVars: Git Repo

Install CSS Vars Instructions

Install the NPM Package:

npm i angular-material-css-vars -S
Enter fullscreen mode Exit fullscreen mode

Install CSS Vars

Update your index file to include the background color class:

Index File Updated

Next update your App Module to use the Angular Material CSSVars:

App Module Updated

To make an easy to use component to let the user change the theme on the front end lets build a standalone component:

Generate ThemePicker Component

You can find the code for this component Here

And we want the user to be able to set the theme and have it stay between sessions so lets create a storage service:

Generate Storage Service

You can find the code for this service Here

Next in the styles.scss file we can add in the default scss variables:

@use "angular-material-css-vars" as mat-css-vars;
@use "@angular/material" as mat;
@import "@angular/material/theming";
@include mat-css-vars.init-material-css-vars();

@include mat-css-vars.mat-css-set-palette-defaults(
  mat.$light-blue-palette,
  "primary"
);
@include mat-css-vars.mat-css-set-palette-defaults(mat.$pink-palette, "accent");
@include mat-css-vars.mat-css-set-palette-defaults(mat.$red-palette, "warn");
Enter fullscreen mode Exit fullscreen mode

Then we can add in specific style classes for each theme, like:

.isLightTheme .logonav {
  background-size: 65px;
  background-origin: content-box;
  background-repeat: no-repeat;
  background-image: url(https://media.jessecarlbergphotography.com/images/logo.png);
}

.isDarkTheme .logonav {
  background-size: 65px;
  background-origin: content-box;
  background-repeat: no-repeat;
  background-image: url(https://media.jessecarlbergphotography.com/images/logowhite.png);
}

Enter fullscreen mode Exit fullscreen mode

And that's it. Easy peasy.

-J

💖 💪 🙅 🚩
jesserules
jesserules

Posted on June 12, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related