Implementing a Material Angular Theme Switching Component
Tags: angular, material
Published: 2023-06-12 18:00:45

## 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](https://github.com/jesseRules/ThemePicker)

![Theme Selector](https://media.jessecarlbergphotography.com/images/blog/themepickerexample.gif)

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

![In Practice](https://media.jessecarlbergphotography.com/images/blog/themeswitcher.jpg)

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](https://media.jessecarlbergphotography.com/images/blog/createnewappwcss.png)

To fix this flub of css instead of scss we are going to use a handy npm package Scss Migrate: [SCSS Migrate Git](https://github.com/Teebo/scss-migrate)


![installmigrationnpm](https://media.jessecarlbergphotography.com/images/blog/installmigrationnpm.png)

Once you have this installed you can run the command:

```
ng g schematics-scss-migrate:scss-migrate
```

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](https://media.jessecarlbergphotography.com/images/blog/migratestep1.png)

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](https://media.jessecarlbergphotography.com/images/blog/migratestep2.png)


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

![App Name](https://media.jessecarlbergphotography.com/images/blog/Appname.png)

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

![migrate to scss](https://media.jessecarlbergphotography.com/images/blog/migratetoscss.png)

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

```
			"projectType": "application",
			"schematics": {
				"@schematics/angular:application": {
					"strict": true
				},
				"@schematics/angular:component": {
					"style": "scss"
				}
			},
```

![Angular Json updated](https://media.jessecarlbergphotography.com/images/blog/angularjsonupdate.png)



 Let's get to theming!

First, let's use an awesome NPM package to do this AngularMaterialCSSVars: [Git Repo](https://github.com/johannesjo/angular-material-css-vars)

![Install CSS Vars Instructions](https://media.jessecarlbergphotography.com/images/blog/installcssvarsinstructions.png)

Install the NPM Package:
```
npm i angular-material-css-vars -S
```

![Install CSS Vars](https://media.jessecarlbergphotography.com/images/blog/installcssvars.png)

Update your index file to include the background color class:

![Index File Updated](https://media.jessecarlbergphotography.com/images/blog/indexfileupdate.png)

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


![App Module Updated](https://media.jessecarlbergphotography.com/images/blog/appmoduleupdate.png)

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](https://media.jessecarlbergphotography.com/images/blog/createthemepickerstandalone.png)

You can find the code for this component [Here](https://github.com/jesseRules/ThemePicker/blob/master/src/app/theme-picker/theme-picker.component.ts)

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](https://media.jessecarlbergphotography.com/images/blog/generatestorageservice.png)

You can find the code for this service [Here](https://raw.githubusercontent.com/jesseRules/ThemePicker/master/src/app/theme-picker/services/theme-storage.service.ts)

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");
```


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);
}

```

And that's it. Easy peasy.

-J