Как изменить цвет шрифта основной палитры в Angular Material2?

В официальной тематической документации Angular Material2 четко говорится следующее:

В Angular Material тема создается путем составления нескольких палитр. В частности, тема состоит из:

  • Основная палитра: цвета, наиболее широко используемые на всех экранах и компонентах.
  • Акцентная палитра: цвета, используемые для плавающей кнопки действий и интерактивных элементов.
  • Палитра предупреждений: цвета, используемые для передачи состояния ошибки.
  • Палитра переднего плана: цвета для текста и значков.
  • Палитра фона: цвета, используемые для фона элемента.

Но в каждом примере они модифицируют только первые три:

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

$candy-app-primary: mat-palette($mat-indigo);
$candy-app-accent:  mat-palette($mat-pink, A200, A100, A400);
$candy-app-warn:    mat-palette($mat-red);
$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

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

Итак, мой вопрос: как я могу изменить палитру переднего плана, чтобы изменить цвет текста для основной или дополнительной палитры?

Есть несколько веб-сайтов ( https://www.materialpalette.com/, https://material.io/color/), которые отображают цветовую палитру для простоты визуализации, но, тем не менее, не говорят, как включить или изменить эту палитру в Angular Material2.

5 ответов

Решение

Вы можете изменить цвет темы по умолчанию, создав собственную карту переднего плана и объединить ее с созданной темой перед ее инициализацией. Вот как:

  1. Создайте объект темы как обычно.

    @import '@angular/material/theming.scss';
    @include mat-core();
    
    // Choose colors
    $my-app-primary: mat-palette($mat-blue-grey);
    $my-app-accent:  mat-palette($mat-light-green);
    $my-app-warn:    mat-palette($mat-red);
    
    // Build theme object (its practically a map object)
    $my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);
    
  2. Создайте свой собственный передний план, используя пользовательскую функцию, возвращающую карту переднего плана, как определено в @angular/material/_theming.scss -> $mat-light-theme-foreground функция.
    Вы можете играть с картой и определять только те поля, которые вы хотите, а остальные оставить по умолчанию.

    @function my-mat-light-theme-foreground($color) {
        @return (
            base:              $color,
            divider:           $black-12-opacity,
            dividers:          $black-12-opacity,
            disabled:          rgba($color, 0.38),
            disabled-button:   rgba($color, 0.38),
            disabled-text:     rgba($color, 0.38),
            hint-text:         rgba($color, 0.38),
            secondary-text:    rgba($color, 0.54),
            icon:              rgba($color, 0.54),
            icons:             rgba($color, 0.54),
            text:              rgba($color, 0.87),
            slider-off:        rgba($color, 0.26),
            slider-off-active: rgba($color, 0.38),
        );
    };
    
    // You can put any color here. I've chosen mat-color($my-app-primary, 700)
    $my-foreground: my-mat-light-theme-foreground(mat-color($my-app-primary, 700));
    
  3. Объедините ранее созданную тему только с картой переднего плана и инициализируйте свою собственную тему.
    Примечание. Поскольку все карты в SCSS являются неизменяемыми, map-merge() возвращает новый экземпляр карты и НЕ изменяет карту на месте - таким образом, у нас есть другая переменная $my-app-theme-custom провести тему результата.

    $my-app-theme-custom: map-merge($my-app-theme, (foreground: $my-foreground));
    
    // Include your custom theme.
    @include angular-material-theme($my-app-theme-custom);
    

Примечание: я использую Angular Material v2.0.0-beta.8

Руководство доступно на веб-сайте документации, расположенном здесь.

Сначала вы определяете палитры для вашей темы, такие как $primary, $accent, $warn (в руководстве у них есть $candy-app- префикс), а затем создать $theme объект:

// Create the theme object (a Sass map containing all of the palettes).
$theme: mat-light-theme($primary, $accent, $warn);

Как только у нас есть тема, которая содержит все палитры, мы можем получить палитру переднего плана:

$foreground: map-get($theme, foreground);

От $foreground палитру мы можем получить любые значения на основе ключа, такие как

secondary-text: rgba(black, 0.54),

или же

text: rgba(black, 0.87)

Вот код для получения secondary-text имущество:

color: mat-color($foreground, secondary-text);

Я перешел на 2.0.0-beta.3 от 2.0.0-beta.2 и структура папок выглядит иначе, вы правы. Сейчас \node_modules\@angular\material\_theming.scss, _palette.scssфайл исчез. Вы можете сделать глобальный поиск по нему: '$mat-dark-theme-background: ('

_theming.scss имеет все цвета, карты и все функции, такие как mat-color

Чтобы изменить цвет текста переднего плана, сначала создайте свою тему как обычно, а затем переопределите theme.color.foreground.text:

      // define theme as you do currently, e.g.
$theme: mat.define-light-theme(...)

/ grab color.foreground map from theme
$color: map-get($map: $theme, $key: color);
$foreground: map-get($map: $color, $key: foreground);

// override text of foreground map
$my-text-color: #3B4956;
$themed-foreground: map-merge($foreground, (text: $my-text-color));

// override foreground of $color map
$themed-color: map-merge($color, (foreground: $themed-foreground));

// override color of theme map
$theme: map-merge($theme, (color: $themed-color));

Продолжите сгенерировать css из темы $ как обычно, т.е. @include mat.all-component-themes($theme)- убедитесь, что это делается только один раз. Один из способов добиться этого:

      _theme.scss 
// contains above theme - ok to include many places

theming.scss 
// generates css - only include once!
@import './theme';
...
@include mat.all-component-themes($theme)

Я удивлен, что это невозможно сделать более простым способом - ожидая, что со временем это изменится. Удачи.

Обновление для углового материала>14

Я использовал ответ nyxz выше, но с Angular 14 единственный способ, которым я смог успешно переопределить передний план темы, - это:

      $my-app-theme: mat.define-light-theme(
  (
    color: (
      primary: $my-app-primary,
      accent: $my-app-accent,
      warn: $my-app-warn
    ),
    typography: $custom-typography
  )
);

$my-app-colors: map.get($my-app-theme, color);

$my-app-olors: map.merge(
  $my-app-colors,
  (
    foreground:  $my-foreground
  )
);

$my-app-theme: map.merge(
  $my-app-theme,
  (
    color: $my-app-colors
  )
);

Вот код:

// Foreground palette for light themes.
$mat-light-theme-foreground: (
  base:            black,
  divider:         rgba(black, 0.12),
  dividers:        rgba(black, 0.12),
  disabled:        rgba(black, 0.38),
  disabled-button: rgba(black, 0.38),
  disabled-text:   rgba(black, 0.38),
  hint-text:       rgba(black, 0.38),
  secondary-text:  rgba(black, 0.54),
  icon:            rgba(black, 0.54),
  icons:           rgba(black, 0.54),
  text:            rgba(black, 0.87)
);

Вы можете найти карту по адресу: \node_modules\@angular\material\core\theming\ _palette.scss

Пример получения "вторичного текста":

$foreground: map-get($theme, foreground);

.foreground-color {
  color: mat-color($foreground, secondary-text);
}
Другие вопросы по тегам