angularsassangular-materialmaterial3angular-material-theming

What is the best practice for having mutiple themes in a single web app? Override or 2nd theme


I have an app that was created for me at https://stackblitz.com/edit/angular-gjkbqm-schlk9?file=index.html

This app shows how to properly use a theme, the explanation was given here

How do I use a font other than Roboto?

My question is now the body is a completly different theme and typography than the body.

I am looking for the best approach to implement this. I know you can override the existing theme, which seems very CSS intensive and makes me question why I started themes in the first place. Or option 2 is to implement a complete theme just for the toolbar.

any advice and help with the implementation would be appreciated

stackblitz is slightly different than my code, but the idea would be the same

navbar.component.html

<mat-toolbar color="tertiary">
  <mat-toolbar-row>
      <span class="highlighted-word">{{title}}</span>
      <mat-button *ngFor="let item of navbarItems" mat-icon-button     [routerLink]="item.route">
        <mat-icon>{{ item.icon }}</mat-icon>
        <span>{{ item.title }}</span>
      </mat-button>
  </mat-toolbar-row>
</mat-toolbar>

nav.component.ts

import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterLink } from '@angular/router';
import { navbarRoutes } from './navbar-routes';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-navbar',
  standalone: true,
  imports: [MatToolbarModule, MatIconModule, MatButtonModule,         RouterLink,CommonModule],
      templateUrl: './navbar.component.html',
      styleUrl: './navbar.component.scss'
    })
    export class NavbarComponent {
      title: string;
      navbarItems = navbarRoutes;

      constructor() {
        this.title = "State Line Rodz NFP";
      }
    }
    nabvar.routes.ts -- custom file from ideas on the web
export const navbarRoutes = [
        {
            icon: 'about',title: 'About Us',route: 'about'
        },
        {
            icon: 'ourteam',title: 'Our Team',route: 'ourteam'
        },
        {
            icon: 'support',title: 'Support',route: 'supportus'
        },
        {
            icon: 'news',title: 'News',route: 'news'
        },
        {
            icon: 'event',title: 'Events',route: 'event'
        },    
        {
            icon: 'membershipinfo',title: 'Membership Info',route: 'membershipinfo'
    },
    {
        icon: 'home',title: 'Home',route: 'home'
    },

]

styles.scss

@use '@angular/material' as mat;
@use './m3-theme.scss' as m3-theme;

@include mat.core();

html {
  @include mat.all-component-themes(m3-theme.$dark-theme);
}

.title{
  min-width: 100%;
  text-align: center;
}

.bodytext{
  width: 80%;
  text-align: center;
}

.flex-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 80%;
  margin: 0 auto;
}

.flex-body {
  flex-grow:1;
  width: 100%;
  padding: 10px;
  margin-bottom: 10px;;
  text-align: center;
}

m3-theme.scss

// This file was generated by running 'ng generate @angular/material:m3-theme'.
// Proceed with caution if making changes to this file.

@use 'sass:map';
@use '@angular/material' as mat;
@include mat.core();

$typography-config: (
  // <- notice!
  plain-family: 'Oswald',
  // <- notice!
  brand-family: 'Merriweather',
  // <- notice!
); // <- notice!


// Note: Color palettes are generated from primary: #000000, secondary: #D28036, tertiary: #E81F27, neutral: #622737
$_palettes: (
  primary: (
    0: #000000,
    10: #1b1b1b,
    20: #303030,
    25: #3b3b3b,
    30: #474747,
    35: #525252,
    40: #5e5e5e,
    50: #777777,
    60: #919191,
    70: #ababab,
    80: #c6c6c6,
    90: #e2e2e2,
    95: #f1f1f1,
    98: #f9f9f9,
    99: #fcfcfc,
    100: #ffffff,
  ),
  secondary: (
    0: #000000,
    10: #2f1500,
    20: #4d2600,
    25: #5d2f00,
    30: #6e3900,
    35: #7f4300,
    40: #914d00,
    50: #af641b,
    60: #ce7d33,
    70: #ee974b,
    80: #ffb77e,
    90: #ffdcc3,
    95: #ffede3,
    98: #fff8f5,
    99: #fffbff,
    100: #ffffff,
  ),
  tertiary: (
    0: #000000,
    10: #410003,
    20: #690007,
    25: #7d000a,
    30: #93000e,
    35: #a90012,
    40: #c00016,
    50: #e92027,
    60: #ff544d,
    70: #ff897f,
    80: #ffb4ac,
    90: #ffdad6,
    95: #ffedea,
    98: #fff8f7,
    99: #fffbff,
    100: #ffffff,
  ),
  neutral: (
    0: #000000,
    4: #17030a,
    6: #23040e,
    10: #3a0718,
    12: #3f0b1c,
    17: #4d1627,
    20: #551d2d,
    22: #5b2131,
    24: #602636,
    25: #632838,
    30: #713343,
    35: #7f3e4e,
    40: #8d4a5a,
    50: #aa6272,
    60: #c77a8c,
    70: #e694a6,
    80: #ffb1c1,
    87: #ffcdd6,
    90: #ffd9df,
    92: #ffe1e5,
    94: #ffe8eb,
    95: #ffecee,
    96: #fff0f1,
    98: #fff8f7,
    99: #fffbff,
    100: #ffffff,
  ),
  neutral-variant: (
    0: #000000,
    10: #201a1b,
    20: #352f30,
    25: #413a3b,
    30: #4c4546,
    35: #585052,
    40: #645c5e,
    50: #7e7576,
    60: #988e90,
    70: #b3a9aa,
    80: #cfc4c5,
    90: #ebe0e1,
    95: #faeeef,
    98: #fff8f8,
    99: #fffbff,
    100: #ffffff,
  ),
  error: (
    0: #000000,
    10: #410002,
    20: #690005,
    25: #7e0007,
    30: #93000a,
    35: #a80710,
    40: #ba1a1a,
    50: #de3730,
    60: #ff5449,
    70: #ff897d,
    80: #ffb4ab,
    90: #ffdad6,
    95: #ffedea,
    98: #fff8f7,
    99: #fffbff,
    100: #ffffff,
  ),
);

$_rest: (
  secondary: map.get($_palettes, secondary),
  neutral: map.get($_palettes, neutral),
  neutral-variant: map.get($_palettes,  neutral-variant),
  error: map.get($_palettes, error),
);
$_primary: map.merge(map.get($_palettes, primary), $_rest);
$_tertiary: map.merge(map.get($_palettes, tertiary), $_rest);

$light-theme: mat.define-theme((
  color: (
    theme-type: light,
    primary: $_primary,
    tertiary: $_tertiary,
  ),
  typography: $typography-config, // <- notice!

));
$dark-theme: mat.define-theme((
  color: (
    theme-type: dark,
    primary: $_primary,
    tertiary: $_tertiary,
  ),
  typography: $typography-config, // <- notice!

));

if I looked at this a week ago, I would not have a clue what's gong on so I am a slow learner and appreciate help


Solution

  • It might be easier just to define a secondary theme and typography, as shown below.

    $typography-config-secondary: (
      plain-family: Roboto,
      brand-family: Open Sans,
      bold-weight: 900,
      medium-weight: 500,
      regular-weight: 300,
    );
    ...
    
    ...
    $theme-secondary: mat.define-theme(
       (
         color: (
           primary: mat.$violet-palette,
           tertiary: mat.$magenta-palette,
         ),
         typography: $typography-config-secondary,
       )
     );
    

    After defining the theme, we usually call the mixin @mixin all-component-themes($theme) { to style all the components.

    Since we want to theme only the toolbar with this new theme, we just declare the single theme mixin toolbar-theme with the secondary theme and this overrides the definitions above for toolbar.

    ...
    body {
      font-family: Roboto, 'Helvetica Neue', sans-serif;
      margin: 0;
      padding: 30px;
      height: 100%;
    
      @include mat.all-component-themes($theme);
      @include mat.toolbar-theme($theme-secondary);
    }
    ...
    

    Full Code:

    @use '@angular/material' as mat;
    
    $typography-config: (
      // <- notice!
      plain-family: 'Edu AU VIC WA NT Pre',
      // <- notice!
      brand-family: 'Edu AU VIC WA NT Pre',
      // <- notice!
    ); // <- notice!
    
    $typography-config-secondary: (
      plain-family: Roboto,
      brand-family: Open Sans,
      bold-weight: 900,
      medium-weight: 500,
      regular-weight: 300,
    );
    
    $theme: mat.define-theme(
      (
        color: (
          theme-type: light,
          primary: mat.$azure-palette,
          tertiary: mat.$blue-palette,
        ),
        typography: $typography-config,
      )
    );
    
    $theme-secondary: mat.define-theme(
      (
        color: (
          primary: mat.$violet-palette,
          tertiary: mat.$magenta-palette,
        ),
        typography: $typography-config-secondary,
      )
    );
    
    body {
      font-family: Roboto, 'Helvetica Neue', sans-serif;
      margin: 0;
      padding: 30px;
      height: 100%;
    
      @include mat.all-component-themes($theme);
      @include mat.toolbar-theme($theme-secondary);
    }
    
    html {
      height: 100%;
    }
    
    @include mat.core();
    @include mat.color-variants-backwards-compatibility($theme);
    @include mat.typography-hierarchy($theme); // <- notice!
    

    Stackblitz Demo