How can I handle multiple themes in an angular component?
Asked Answered
M

1

8

I'm working on an Angular 9 project where I'm creating two themes and each theme has it's own css output file. I modified the angular.json file to handle that:

"styles": [
  {
    "input": "src/styles/themes/light-theme.scss",
    "lazy": true,
    "bundleName": "light-theme"
  },
  {
    "input": "src/styles/themes/dark-theme.scss",
    "lazy": false,
    "bundleName": "dark-theme"
  }
],

light-theme and dark-theme are my input files, where I'm setting variables like:

  • $background-color
  • $button-color
  • $text-color
  • etc, etc.

My problem is that I cannot use those variables from each component, because my component won't know what those variables are. I cannot import one or another theme, because I would like to use the values that I declared in the input file. How should I handle this? Is there any way of "importing" the input file I wrote on my angular.json file?

Thanks!

Myrtia answered 15/5, 2020 at 19:48 Comment(0)
S
8

If you define sass variables in your global styles, you won't be able to access them after when you dynamically change the theme. This is because the dynamically loaded theme will contain css rules only, not sass; besides at run time your components scss has also already compiled to css so there is no more notions of sass variables either way.

What you can do instead is use CSS variables, which have good browser support (apart from IE and opera mini).

So for instance, you can define these variables in your theme files

dark-theme.scss

:root{
  --button-background: darkgrey;
  --button-color: white;
}

light-theme.scss

:root{
  --button-background: lightgrey;
  --button-color: black;
}

Then in your component, use these variables

component.scss

button
{
  cursor: pointer;
  padding: 10px;
  border: 0;
  color:var(--button-color);
  background-color:var(--button-background);
}

Then, when you dynamically load the light theme, it will override the existing variables. If you then dynamically remove light-theme.css, it'll go back to using your dark theme's variables.

Schaab answered 18/5, 2020 at 16:26 Comment(5)
Yeah, that's how I solved it for now. I was trying to avoid mixing css variables with scss variables. Why can't I override my scss variables in each input file and use them from my components?Myrtia
Because the theme scss file has already been compiled to css when you load it, so there is no more notions of variablesSchaab
So my components scss files and my input scss files are compiled individually?Myrtia
In your component, if your reference one of your 2 themes (say dark), the component scss will be compiled using that theme's values. Dynamically importing another theme (light) will have no impact, since the overridden sass variable from that 2nd theme will only be included with their overridden values in light.css, nowhere else.Schaab
You can also create a variable to denote which theme is used. Say $is-dark. So you can add conditions on basis of that in component scss file. This can be used for specific scenarios such as both themes have different variables.Bangalore

© 2022 - 2024 — McMap. All rights reserved.