Components: Support additional colors outside primary, accent, warn

Created on 22 Jun 2018  路  12Comments  路  Source: angular/components

Bug, feature request, or proposal:

Feature Request

What is the expected behavior?

Allow additional color pallets

What is the current behavior?

Only 3 color pallets

What is the use-case or motivation for changing an existing behavior?

Material design specifications no longer call for the use of three color states, instead offering the following recommendation

  • Primary color

  • Secondary color

  • Surface, background, and error colors

  • Alternative Colors: The Material Design color system supports alternative colors, which are colors used as alternatives to your brand鈥檚 primary and secondary colors (they constitute additional colors to your theme). Apps can use alternative colors to establish themes that distinguish different sections.

https://material.io/design/color/the-color-system.html#color-theme-creation

P3 materiacore feature needs discussion

Most helpful comment

I figure out how I can make success color in Angular Material way.

  1. First make your own palette
  2. merge it to theme
  3. make corresponding mat-class
  4. use color="foo"

Here is example

$custom-collection: (
    warning :  #FFC116,
    success :  #0a630f,
    danger:    #c00000,
    contrast: (
        warning :  #000000,
        success :  #FFFFFF,
        danger:    #FFFFFF,
    )
);

$my-app-custom: mat-palette($custom-collection, custom);
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn); // this row your should have already in your code where you select palettes for primary, accent and warn
$my-app-theme: map_merge($my-app-theme, (custom: $my-app-custom));
$custom: map-get($my-app-theme, custom);

Then you can use $custom in your component like this

background-color: mat-color($custom, success);
color: mat-color($custom, success-contrast);

But better solution is to make mat-success-class like this

.mat-success {
    background-color: mat-color($custom, success);
    color: mat-color($custom, success-contrast);
  }

Then you can use color directive like this

<button mat-flat-button color="success" >Success</button>

This works because color="foo" generates class="mat-foo" for element.

All 12 comments

This would be extremely valuable in applications where a brand color is used for specific components such as the main app bar but is not the primary color. When the brand color is red for example, using it as the primary theme color is problematic, since primary colored input fields look like they are in error. But a red toolbar on the other hand does not suggest an error.

As regards as Material Theming, alternative colors should be supported: https://material.io/design/color/the-color-system.html#color-theme-creation (scroll down to alternative colors).

If you need to add alternative or custom colors, just add a class on the control itself in your template and override the color with what you need. If you are using brand colors or have some other color, just create re-usable sass variables and create custom css for your custom application. You can have multiple css classes on any control, just have to make sure you have the correct specificity. Remember, material ui is built upon html and css, so nothing is preventing you from adding custom inline style or css classes to a control to fit your needs. Also you are not limited by the material color system, so you can use any color you want - hex, rbga, hsla combinations...

@tqle thanks for the suggestion, but I think the point of this issue is _theming_ support for additional colors as well as having the base components support additional colors. Knowing how to use CSS to implement whatever colors we want in our own components is not the problem.

Possibly related: #11390.

we need a success color (likely green), esp for form validations and stuff. Im fine if the material team doesnt want to use a success color design wise, but many users need a green - success color sometimes somewhere in there angular/material app. So they could implement a success color for those who need it.

Sometimes we want a different thing inside our application, sometimes we need to create social media butons, in which have their own color specification, _et cetera_.

@smnbbrv Any updates on this?

I figure out how I can make success color in Angular Material way.

  1. First make your own palette
  2. merge it to theme
  3. make corresponding mat-class
  4. use color="foo"

Here is example

$custom-collection: (
    warning :  #FFC116,
    success :  #0a630f,
    danger:    #c00000,
    contrast: (
        warning :  #000000,
        success :  #FFFFFF,
        danger:    #FFFFFF,
    )
);

$my-app-custom: mat-palette($custom-collection, custom);
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn); // this row your should have already in your code where you select palettes for primary, accent and warn
$my-app-theme: map_merge($my-app-theme, (custom: $my-app-custom));
$custom: map-get($my-app-theme, custom);

Then you can use $custom in your component like this

background-color: mat-color($custom, success);
color: mat-color($custom, success-contrast);

But better solution is to make mat-success-class like this

.mat-success {
    background-color: mat-color($custom, success);
    color: mat-color($custom, success-contrast);
  }

Then you can use color directive like this

<button mat-flat-button color="success" >Success</button>

This works because color="foo" generates class="mat-foo" for element.

@JanneHarju Thanks for that workaround.

Also if you are just wanting to overwrite styles for 1 material design component (in my case SlideToggle) you can do so without adding the code above. Just add the mat-{your name} to the stylesheet.

Example for mat-postive where I want to change the ON toggle style only:

.mat-slide-toggle.mat-positive.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
  background-color: #55cc00;
}

.mat-slide-toggle.mat-positive.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
  background-color: white;
}

then use it like this:

<mat-slide-toggle color="positive"> Edit Multiple </mat-slide-toggle>

@ccarns
The comment in _theming.scss (@angular/[email protected]) says:

// If the theme has been constructed through the legacy theming API, we use the theme object
// as color configuration instead of the dedicated color property. We do this because for
// backwards compatibility, we copied the color configuration from $theme.color to $theme.
// Hence developers could customize the colors at top-level and want to respect these changes
// TODO: Remove when legacy theming API is removed.

So instead of simple merge

$my-app-theme: map_merge($my-app-theme, (custom: $my-app-custom));

i had to replicate the definition under a 'color' property then use deep merge to make all stuff working properly (eg mat-get-color-config() function)

@use "sass:map";

$custom-collection: (
    warning :  #FFC116,
    success :  #0a630f,
    danger:    #c00000,
    contrast: (
        warning :  #000000,
        success :  #FFFFFF,
        danger:    #FFFFFF,
    )
);

$my-app-custom: mat-palette($custom-collection);
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn); // this row your should have already in your code where you select palettes for primary, accent and warn
$my-app-theme: map.deep-merge(
  $my-app-theme, 
  (
    custom: $my-app-custom,
    color: (
      custom: $my-app-custom  
    )
  )
);
$custom: map-get($my-app-theme, custom);

Thank you for sharing that @notbear . Is that documented somewhere and should it be documented? I mean somewhere else than in code. For example in Angular Material documentation and in Angular Update Guide https://update.angular.io/ .

Was this page helpful?
0 / 5 - 0 ratings

Related issues

julianobrasil picture julianobrasil  路  3Comments

constantinlucian picture constantinlucian  路  3Comments

savaryt picture savaryt  路  3Comments

RoxKilly picture RoxKilly  路  3Comments

Miiekeee picture Miiekeee  路  3Comments