Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Custom Component Theming

I am trying to use colors from my custom color pallette in my custom Angular Material theme for some other components.

For example a div with a mat-toolbar and an icon with margin, which should be filled with primary background color.

The Angular Material guides about theming says:

The theme file should not be imported into other SCSS files. This will cause duplicate styles to be written into your CSS output.

But in the guide with component theming, it says the following:

You can consume the theming functions and Material palette variables from @angular/material/theming. You can use the mat-color function to extract a specific color from a palette. For example:

// Import theming functions
@import '~@angular/material/theming';
// Import your custom theme
@import 'src/unicorn-app-theme.scss';

// Use mat-color to extract individual colors from a palette as necessary.
// The hue can be one of the standard values (500, A400, etc.), one of the three preconfigured
// hues (default, lighter, darker), or any of the aforementioned prefixed with "-contrast".
// For example a hue of "darker-contrast" gives a light color to contrast with a "darker" hue.
// Note that quotes are needed when using a numeric hue with the "-contrast" modifier.
// Available color palettes: https://www.google.com/design/spec/style/color.html
.candy-carousel {
  background-color: mat-color($candy-app-primary);
  border-color: mat-color($candy-app-accent, A400);
  color: mat-color($candy-app-primary, '100-contrast');
}

The theme is getting imported again in the component, where they extract the color with functions from the material theming.

I am confused, what is the right way, to use colors on non angular material components or event material components which have no color input?

like image 535
Florian Leitgeb Avatar asked Apr 27 '18 22:04

Florian Leitgeb


People also ask

How do you use material theming?

To use Material Theming with color, start by choosing suitable colors to apply to your UI. Color can be selected in several ways: Generate colors with the inline tool in the Color section. Select colors from the Material Palettes' harmonious colors schemes.

What is theming in angular?

Angular Material's theming system lets you customize color and typography styles for components in your application. The theming system is based on Google's Material Design specification. This document describes the concepts and APIs for customizing colors.

Can I change angular material theme?

it's very easy to create a custom angular material theme. This will allow you to specify primary, accent and warning colors that will be used on Angular Material components. Your custom theme will be a Sass file and in our case, we'll call it theme. scss and place it in our app's /src folder.


1 Answers

It's late to answer to this question, but I had the same problem and spent a lot of time on trying to figure out how it works. The main problems were:

  • The Angular Material documentation on customizing own components doesn't tell you the whole story as Florian stated in his question.
  • I didn't find an example in an online discussion with all the required files and changes so that it worked.

I found two helpful examples on Stackblitz:

  • This one shows how to manipulate background and foreground elements from your theme.
  • This one shows how to switch between custom themes.

However, I needed something different:

  • I wanted to use own colors.
  • I wanted to use them in own components on elements like h1 or div.
  • Of course I wanted to avoid the duplication of styles which is recommended but not explained in the Angular Material theming docs.

This post on GitHub helped me the most. This discussion was also helpful in terms of switching from CSS to SCSS.

For anyone with the same problem I would like to share my solution so that you have it all in one spot:

1. Get your color definitions

Suppose you want to use #3F51B5 as primary and another one as accent color. Go to this site, enter each of your colors and download the definitions (pick "Angular JS 2 (Material 2)" and copy the content of $md-mcgpalette0: (___).

2. Create theme_variables.scss and put it in your src directory.

Insert your color definitions which you just downloaded.

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

$app-blue: (
    50 : #e8eaf6,
    100 : #c5cbe9,
    200 : #9fa8da,
    300 : #7985cb,
    400 : #5c6bc0,
    500 : #3f51b5,
    600 : #394aae,
    700 : #3140a5,
    800 : #29379d,
    900 : #1b278d,
    A100 : #c6cbff,
    A200 : #939dff,
    A400 : #606eff,
    A700 : #4757ff,
    contrast: (
        50 : #000000,
        100 : #000000,
        200 : #000000,
        300 : #000000,
        400 : #ffffff,
        500 : #ffffff,
        600 : #ffffff,
        700 : #ffffff,
        800 : #ffffff,
        900 : #ffffff,
        A100 : #000000,
        A200 : #000000,
        A400 : #ffffff,
        A700 : #ffffff,
    )
);

$app-yellow: ( 
    // repeat for your second color
);

$app-primary: mat-palette($app-blue, 500);
$app-accent: mat-palette($app-yellow, 500);

// warn palette is optional (defaults to red).
$app-warn: mat-palette($mat-red);

// Custom Sass colors vars (will be available in all the project)
$primary: mat-color($app-primary);
$accent: mat-color($app-accent);
$warn: mat-color($app-warn);

You could also separate the palette from the variable definitions into two different files but I left it like that.

3. Create theme.scss and put it in your src directory:

@import "~@angular/material/theming";
@import "./theme_variables.scss";
@import "./fonts/fonts.css"; // in case you have this file for your fonts

@include mat-core();

$app-theme: mat-light-theme($app-primary, $app-accent, $app-warn);

@include angular-material-theme($app-theme);

4. Create styles.scss and put it in your src directory:

@import "./theme.scss";

// add the rest of your global styles

5. Update angular.json:

... "styles": [
          "src/styles.scss",
          "src/theme.scss"
        ] ...

6. In your component, where you want to use the theme colors, rename the example.component.css-file to .scss and edit it:

@import "../../theme_variables.scss";

h1 { 
    color: $primary;
}

h2 { 
    color: $accent;
}
// put the rest of your styling

7. Update the style url in your example.component.ts file:

@Component({
  selector: "example",
  templateUrl: "./example.component.html",
  styleUrls: ["./example.component.scss"] // <-- update the file type
})

8. Switch to scss by deafult

Run ng config schematics.@schematics/angular:component.styleext scss to create scss files for new components in the future.

Update: If on component creation still no scss file is created, the reason might be that you have to configure scss extensions for all your projects. See this discussion for further information. What helped me: ng config projects.<projectname>.schematics.@schematics/angular:component.style scss


If you don't need the variables in all components, you can leave their css files like that. Whenever you want to use the theme colors in a component, change the css file to scss, import the theme variables and update the styleUrl in the component (step 6 + 7).

I am quite new to Angular and there are probably things you can do better. So anyone who has further suggestions, please let me know.

like image 188
Jasmin Avatar answered Oct 29 '22 19:10

Jasmin