I have angular wrapper module (app module) and many independent lazy-loaded sub-modules. Each sub-module behaves like a totaly separate app and needs its own angular material theme.
I've created custom theme for each sub-module and tried to reference the custom theme in each of components' .scss file with relative path.
Some of the Material components apply the custom theme (button) and some (mat-form-field) just take the theme specified in styles.scss.
One way I can avoid this is including each custom theme in 'styles' array of angular.json, but I'm afraid that, by doing this, each independent sub-module (app) will have to load every themes' compiled .css and it'll be overhead.
Is there any known issue with this or any better solution?
home-app.component.scss:
@import './theme.scss';
VS.
angular.json
...
"styles": [
"src/styles.scss",
"src/app/orgs/home/theme.scss" // <-- FIXED BY ADDING THIS
],
...
Expected: Theme declared in the home-app.component.scss will be loaded and applied to every material component used in home-app.component.html
Actual: If I don't add "src/app/orgs/home/theme.scss" to angular.json, the custom theme declared in styles.scss will be applied to some material components used in home-app.component.html, and some material components will use the imported theme specified in home-app.component.scss
Did you try to add it directly into styles array of your Components?
@Component({
selector: 'app-home',
template: 'your-template.html',
styles: ['your-style.scss', 'your-theme.scss']
})
Another thing you can do is to use ShadowDom as your ViewEncapsulation :
@Component({
selector: 'app-home',
template: 'your-template.html',
styles: ['your-style.scss', 'your-theme.scss'],
encapsulation: ViewEncapsulation.ShadowDom
})
I think i understood your problem and here is a solution for you :)
So when you create a new ng-project with the cli with opt in material-theming, you will get a inital theming configuration like the following (or you can find the config in the Material Guides)
import '~@angular/material/theming';
// Plus imports for other components in your app.
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$candy-app-primary: mat-palette($mat-indigo);
$candy-app-accent: mat-palette($mat-pink, A200, A100, A400);
// The warn palette is optional (defaults to red).
$candy-app-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($candy-app-theme);
The most important part of this is to remember that you must include just once the mat-core()
in your application (in order to have a single material styles css file).
After that you can create custtom themes by including import '~@angular/material/theming';
wherever desired in the application and apply the theme by wrapping it in a css calss. For example after you include the mat-core
once in you root .scss file, in a lazy loaded module you can do the following thing:
@import "~@angular/material/theming";
.theme1 {
$theme-primary: mat-palette($mat-red);
$theme-accent: mat-palette($mat-lime, A200, A100, A400);
// The warn palette is optional (defaults to red).
$theme-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$theme-theme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($theme-theme);
}
<div class="theme1">
<mat-toolbar color="accent">
<button color='primary' mat-button routerLink="/1">Go to 1</button>
<button color='primary' mat-button routerLink="/2">Go to 2</button>
</mat-toolbar>
</div>
Of course instead of two buttons you can also place your router-outlet inside the container with class theme1
and achive the desired result (different theme per lazy loaded module). Keep in mind that we are just importing import '~@angular/material/theming';` in the places where we need custom theming.
Here is a live example: CodeSandbox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With