Get material 2 color scheme themes / palettes for other elements

I am creating an application, but I want to keep a consistent color scheme that can be changed using the settings, so I use Material (2) with an angular (2+), but I'm not sure how to get a color scheme for elements that do not directly offer the option to color them with color="primary"so that I can only try to figure out how to get the color / color scheme that my Material 2 theme uses. And I want it to change when the theme changes, for example, my navigation bar will adapt to change the theme because it is set to

<mat-toolbar color="primary" class="fixed-navbar mat-elevation-z10">

But the mesh element from Material 2 does not accept the same argument, so I still have an attempt to style it in a fairly close color or just not match it at all (and it will not adapt to theme changes), as shown here:

enter image description here

I want it to match the color of the theme mat, which is here (and changes when you select options in the settings of the navigation bar)

@import '~@angular/material/theming';

@include mat-core();



$candy-app-primary: mat-palette($mat-red);
$candy-app-accent:  mat-palette($mat-deep-orange, A200, A100, A400);
$candy-app-warn:    mat-palette($mat-red);
$candy-app-theme: mat-dark-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.
.default {
  @include angular-material-theme($candy-app-theme);
}
.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include angular-material-theme($light-theme);
}
@include angular-material-theme($candy-app-theme);
+14
source share
5 answers

I found a great workaround !!!! I am so excited to show it because it was stopping me from realizing it for ages. So here it goes; First, change all your CSS files to Scss;

For existing projects

  • Run in console ng set defaults.styleExt=scss

  • Rename all existing .cssfiles to.scss

  • styles .angular-cli.json .css .scss
  • , WebStorm Refactor, , styleUrls .css .scss

  • ng new your-project-name --style=scss

  • scss ng set defaults.styleExt=scss --global

theme.scss , : where themes are

style.scss ( , background-color, , ):

: @mixin styles.scss *name*.component.scss , !

@import '~@angular/material/theming';

// Define a custom mixin that takes in the current theme
@mixin theme-color-grabber($theme) {
  // Parse the theme and create variables for each color in the pallete
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);
  // Create theme specfic styles
  .primaryColorBG {
    background-color: mat-color($primary);
  }
  .accentColorBG {
    background-color: mat-color($accent);
  }
  .warnColorBG {
    background-color: mat-color($warn);
  }
}

theme.scss, 2, , : Material 2 Github -

theme.scss style.scss, theme.scss /src/app/theme.scss , /src/styles.scss ;

@import '../styles';

@mixin ( , , ).

angular-material-theme, :

@include theme-color-grabber($theme);
@include angular-material-theme($theme);

, , , :

.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include theme-color-grabber($light-theme);
  @include angular-material-theme($light-theme);

}

, theme-color-grabber , , , , .

themes.scss :

@import '~@angular/material/theming';
//We import our custom scss component here
@import '../styles';

@include mat-core();

$theme-primary: mat-palette($mat-red);
$theme-accent:  mat-palette($mat-deep-orange, A200, A100, A400);
$theme-warn:    mat-palette($mat-red);
$theme: mat-dark-theme($theme-primary, $theme-accent, $theme-warn);
//
@include theme-color-grabber($theme);
@include angular-material-theme($theme);
.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include theme-color-grabber($light-theme);
  @include angular-material-theme($light-theme);

}

, , !, , mat-grid-tile "" ( color = '', , -toolbar), , :

: scss import '<path-to>/theme.scss' . theme.scss styles.scss !

<mat-grid-list cols="4" rows="4" rowHeight="100px">
  <mat-grid-tile
    colspan="4"
    rowspan="5"
  class="primaryColorBG">
    <div fxLayout="column" fxLayoutAlign="center center">
      <h1 class="title-font">Callum</h1>
      <h1 class="title-font">Tech</h1>
    </div>
    <p>
      Ambitious and ready to take on the world of Information Technology,<br>
      my love for programming and all things I.T. has not wavered since I first got access<br>
      to my fathers computer at age 9.
    </p>
  </mat-grid-tile>

</mat-grid-list>

- !

Red theme

enter image description here

+28

css4, ,

background: var(--color-primary)

css4

@import '~@angular/material/theming';
// 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/
$app-primary: mat-palette($mat-blue);
$app-accent:  mat-palette($mat-orange);
$app-warn:    mat-palette($mat-red);
$app-success: mat-palette($mat-light-green);

// Create the theme object (a Sass map containing all of the palettes).
$app-theme: mat-light-theme($app-primary, $app-accent, $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($app-theme);

$primary: map-get($app-theme, primary);
$accent: map-get($app-theme, accent);

:root {
  --color-primary: #{mat-color($app-primary)};
  --color-accent: #{mat-color($app-accent)};
  --color-warn: #{mat-color($app-warn)};
  --color-success: #{mat-color($app-success)};
}

CSS

background: var(--color-primary)
+8

UPDATE:

:

https://github.com/mirismaili/angular-material-dynamic-themes

If you only need the answer of the asked question, probably is better to refer to the first version of the answer, below. Also, I recommend to read this section of the above repo documentation: Use material themes for other elements.

But if want other capabilities you see in the below video, I recommend this new approach.

Video

Thank StackBlitz


:

enter image description here


:

styles.scss ( themes.scss, ):

@import '~@angular/material/theming';

@include mat-core();

@mixin define-css-classes($theme) {
    @include angular-material-theme($theme);

    $primary: map-get($theme, primary);
    $accent: map-get($theme, accent);
    $warn: map-get($theme, warn);
    $background: map-get($theme, background);
    $foreground: map-get($theme, foreground);

    // CSS THEME-DEPENDENT-STYLES ARE HERE:
    .theme-dependent-colors {
        background: mat-color($primary);
        color: mat-color($accent);
    }
}

/**
* Define your custom themes in this map. 
* The 'key' of each member is the name of CSS class for that theme. 
* To better understand the schema of the map, see '@each' loop below and especially pay attention to 'map-has-key()' functions.
*/ 
$app-themes: (
        indigo-pink : (primary-base: $mat-indigo, accent-base: $mat-pink),
        deeppurple-amber: (primary-base: $mat-deep-purple, accent-base: $mat-amber),
        pink-bluegrey : (primary-base: $mat-pink, accent-base: $mat-blue-gray, is-dark: true),
        purple-green : (primary-base: $mat-purple, accent-base: $mat-green, is-dark: true),
);

@each $css-class, $theme in $app-themes {
    $primary: if(map-has-key($theme, primary), map-get($theme, primary), mat-palette(map-get($theme, primary-base)));

    $accent: if(map-has-key($theme, accent), map-get($theme, accent), mat-palette(map-get($theme, accent-base)));

    $warn: if(map-has-key($theme, warn), map-get($theme, warn), mat-palette(
            if(map-has-key($theme, warn-base), map-get($theme, warn-base), $mat-red)
    ));

    .#{$css-class} {
        @include define-css-classes(mat-light-theme($primary, $accent, $warn));
    }

    .#{$css-class}-dark {
        @include define-css-classes(mat-dark-theme($primary, $accent, $warn));
    }

    .theme-primary.#{$css-class} {
        background-color: mat-color($primary);
    }

    ...
}

setTheme() (. ):

import {Component, HostBinding} from '@angular/core';
import {OverlayContainer} from "@angular/cdk/overlay";

const THEME_DARKNESS_SUFFIX = '-dark';

export class AppComponent {
    @HostBinding('class') activeThemeCssClass: string;
    isThemeDark = false;
    activeTheme: string;

    setTheme(theme: string, darkness: boolean = null) {
        if (darkness === null)
            darkness = this.isThemeDark;
        else if (this.isThemeDark === darkness) {
            if (this.activeTheme === theme) return;
        } else
            this.isThemeDark = darkness;

        this.activeTheme = theme;

        const cssClass = darkness === true ? theme + THEME_DARKNESS_SUFFIX : theme;

        const classList = this.overlayContainer.getContainerElement().classList;
        if (classList.contains(this.activeThemeCssClass))
            classList.replace(this.activeThemeCssClass, cssClass);
        else
            classList.add(cssClass);

        this.activeThemeCssClass = cssClass;
    }

    constructor(overlayContainer: OverlayContainer) {
        this.setThemeClass('indigo-pink', false); // Default theme
    }
}

.


CAVEAT: 8 (4 + 4 ) styles.css ~420 kB ( ).

+3

, , , - , , , myangularthemefile.scss :

@import '~@angular/material/theming';
@include mat-core();

...

.matcolorprimary{
    color: mat-color($mitjans-primary)
}

.matcoloraccent {
    color: mat-color($mitjans-accent);
}

.matcolorwarn {
    color: mat-color($mitjans-warn);
}

HTML-, .

, ...

sass- shadow dom ?

+1
  1. SASS:
    @mixin SASS ( CSS). , Angular-Cli SASS: https://scotch.io/tutorials/using-sass-with-the-angular-cli

  2. @mixin :
    , , @mixin .scss. . @mixin, :

// --- file: my-component_1.scss ---
@import '~@angular/material/theming'; // we need to add this so we could use Material functions
@mixin set-theme-component-1($theme)
{
  // Extract whichever individual palettes you need from the theme.
  $primary-palette: map-get($theme, primary);
  $accent-palette:  map-get($theme, accent);
  $warn-palette:    map-get($theme, warn);

  .component-container
  {
    background-color: mat-color($primary-palette); // use the mat-color function to extract the color from the palette
    border-color: mat-color($warn-palette);
  }
}

// Style rules that aren't theme/color related (size, font, etc)
.component-container
{
  width: 100%;
  ...
}
  1. :
    ( ) @mixin , :
// --- file: app.theme.scss ---
@import '~@angular/material/theming';
@include mat-core(); // include this only once in your code!!!

// each custom component that uses theme colors will be imported here - we need there @mixin
@import './some-path/some-folder/my-component_1'; // no need to specify .scss suffix

@mixin set-theme($theme) // define a new @mixin that will be invoked each time the theme is changed
{
  @include set-theme-component-1($theme); // invoke the mixin we defined for component_1
  // repeat this for each component that uses theme colors
}

// define your themes:
.theme-light
{
  $light-primary: mat-palette($mat-indigo);
  $light-accent:  mat-palette($mat-pink, A200, A100, A400);
  $light-warn:    mat-palette($mat-red);
  $light-theme:   mat-light-theme($light-primary, $light-accent, $light-warn);

  @include angular-material-theme($light-theme);
  @include set-theme($light-theme); // once the theme was set, invoke the mixin
}

.theme-dark
{
  $dark-primary:  mat-palette($mat-teal, A400);
  $dark-accent:   mat-palette($mat-grey, 800);
  $dark-warn:     mat-palette($mat-red, 700);
  $dark-theme:    mat-dark-theme($dark-primary, $dark-accent, $dark-warn);

  @include angular-material-theme($dark-theme);
  @include set-theme($dark-theme); // once the theme was set, invoke the mixin
}

:-)

, , ( , ).
- ThemeService, . OverlayContainer ( Angular , ).
- (theme-dark ) DOM.
- mat-app-background DOM. .
- - , .

You can continue reading here: https://material.angular.io/guide/theming

or look there on the Github project: https://github.com/angular/material2/blob/master/src/lib/core/theming/_theming.scss

0
source

Source: https://habr.com/ru/post/1687526/


All Articles