DEV Community

Cover image for Let's implement a Theme Switch 🎨 like the Angular Material Site

Let's implement a Theme Switch 🎨 like the Angular Material Site

Siddharth Ajmera 🇮🇳 on March 19, 2020

DISCLAIMER: While I write this article, I'll try to be as vocal as I can about how I implement something. So hopefully, if you're new to Angular o...
Collapse
 
negue profile image
negue

Great article and example on how to create a theme-switch :)

With this way node_modules/@angular/material/prebuilt-themes/${themeToSet}.css I see two disadvantages:

  • You need to add the themes to your assets to the build output (node_modules probable not exist anymore when you serve your app outside of the CLI)
  • You need to load (to the browser) the same-ish payload for each theme

IMO, a better way would be to use @johannesjo Helper Library: Demo - GitHub

With this you only load your the theme-boilerplate once and change all colors using CSS-Vars in browser. This also enables to allow your user's to have a custom theme.

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Hi Negue,

Good point. 😃 I did realise this issue with the approach. I'll probably cover the CSS vars approach in a future article.

Thanks a lot for the feedback 🙌🏻🙂

Collapse
 
splaktar profile image
Michael Prentice

Thank you for sharing this article and your analysis of reproducing the Angular Material theme picker. I did a good deal of work last year to make it more accessible for screen reader and keyboard users.

However I am a little worried that your final solution may be less accessible (I haven't had time to try it in a screen reader or keyboard yet as I am on my phone).

I would suggest that the menu trigger be a button with the mat-icon-button attribute rather than just a bare mat-icon.

I can understand not replicating our approach for indicating the selected theme menu item, but it would be helpful to somehow indicate which theme is active in your implementation.

Thanks again!

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Ahhh! Great feedback. 😍 I'll update the article accordingly. 🙂

Thank you soo much for sharing this and helping me improve the article 🙌🏻

Collapse
 
alexandrutanasescu profile image
Alex

Hi! And what an awesome article! I wish i could've reached it before starting to implement the theme changer from the angular material docs site on my own. This really breaks it down to the core of what the mechanism actually is and makes it easier to understand.

One mention: setting resolveJsonModule and and esModuleInterop to true in the compilerOptions, in
tsconfig.app.json/tsconfig.json does not seem to be all there is to this trick. i am using node 10.15 and npm 6.9.0 with angular 9.1.1 and it still can't import the json as a module. However, this is not an issue due to the fact that you can just declare the options as a static map/list and import it where needed.

I am really curious how you would go about implementing the theme change for custom components -> as in getting access to the $primary and/or $accent in custom component css.

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Hi Alex,

Thank you soo much for your kind words. 🙂

Regarding implementing the theme change for custom components, I'm afraid I haven't tried it so far.

Whenever I get a chance to do it, I'll probably write another article about it, and update you here. 🙂

Thanks,
Siddharth

Collapse
 
bhavikcpatel profile image
ßhåvïk þå†êl • Edited

One suggestion, there is no need to specify material modules in AppMaterialModule's imports array if you're just using to export. Once can simply list required modules in export array without importing them.

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Ah! That's a great suggestion. Thank you soo much Bhavik. :)

I've updated the article accordingly.

Collapse
 
gaurangdhorda profile image
GaurangDhorda

i am getting this error...
Refused to apply style from 'localhost:4200/node_modules/@angul...' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

Collapse
 
stephaneeybert profile image
Stephane Eybert

You can't reference a file in the node_modules directory. You could copy the 4 themes under your src directory.

Collapse
 
mdamink profile image
M-Damink

@stephaneeybert What do you mean by this exactly? I also have a mime error. I tried A LOT of possible solutions but I can't get it to work. In my console it says a 404 error..

Collapse
 
amiraziz profile image
amiraziz • Edited

i use your code in our project . thank you.
and question is how can i use theme in sass? with material method i can pass $mat-indigo to component sass, in this method you change it prgrammatically with js. can i use changed theme in component scss file??

Collapse
 
briancodes profile image
Brian

Good job looking into how the Angular site implemented it - I always presumed the were using CSS variables 👍

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Thank you Brian. Glad you liked the article. 🙂

Collapse
 
askudhay profile image
Udhay

Well written Siddharth. Good one! 👍🏼👏🏼🙌🏼

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Thank you Udhay :) Glad you liked it.

Collapse
 
pandiyancool profile image
Pandiyan Murugan

Welcome to Dev.to nanba!

Collapse
 
siddajmera profile image
Siddharth Ajmera 🇮🇳

Thank you Pandiyan 🙌🏻🙂

Collapse
 
stephaneeybert profile image
Stephane Eybert

Hello Siddarth,
How did you find the color codes of the 4 prebuilt themes ?
"backgroundColor": "#fff"
Is there anyway to get them programatically ?
Thanks for the article !
Stephane