嵌套Angular Material自定义组件主题

时间:2019-07-17 17:49:19

标签: css angular sass angular-material material

我创建了两个自定义的Angular Material主题(蓝色,红色)。

根据"Theming your components"材料文档,我有一个要使用主题设计的IconComponent(选择器:my-app-icon)。

现在,在我的styles.scss中,我有:

@mixin icon-theme($theme) {
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);

  my-app-icon {
    background-color: mat-color($primary);
    color: mat-color($accent, A400);
  }
}

.blue-theme {
   @include angular-material-theme($blue-theme);
   @include icon-theme($blue-theme);
}

.red-theme {
   @include angular-material-theme($red-theme);
   @include icon-theme($red-theme);
}

效果很好,但是如果我想嵌套主题,例如:

<div class="blue-theme">
  <my-app-icon></my-app-icon>
  <div class="red-theme">
    <my-app-icon></my-app-icon>
  </div>
</div>

仅第一个主题声明(此处为blue-theme有效(对于两个图标)。这是有道理的,因为我的mixin暗示了my-app-icon {}的双重声明。

如何获得预期的行为(第一个图标为蓝色,第二个图标为红色)?

1 个答案:

答案 0 :(得分:0)

在应用程序中同时使用多个主题 所需的方法与您全局实现的 switchable 主题不同。

您需要在组件中实现“主题”或颜色功能-类似于Angular Material通过CanColor基类对某些组件的“颜色”选项(主要,强调,警告)进行的方式。

简而言之,您的组件具有某种机制来指定其主题,并在组件内实现样式。

那可能像一个类一样简单:

用法:

<my-app-icon class="red-theme"></my-app-icon>

SCSS:

:host(.red-theme) {
  @include icon-theme($red-theme); 
}
:host(.blue-theme) {
  @include icon-theme($blue-theme); 
}

或者可以更复杂一些,例如主题属性为Input

用法:

<my-app-icon theme="red"></my-app-icon>

TS:

@Input() theme: string = 'red'; // defaults to red
@HostBinding('class.red-theme') get isRedTheme() { return this.theme === 'red'; };
@HostBinding('class.blue-theme') get isBlueTheme() { return this.theme === 'blue'; };

与上面相同的SCSS在这里适用。

您可以选择仅对组件的必要部分设置样式:

IconComponent模板:

<mat-icon [ngClass]="{'blue-theme': theme === 'blue', 'red-theme': theme !== 'blue'}">{{iconName}}</mat-icon>

SCSS:

:host {
  mat-icon
    &.red-theme {
      color: red;
    }
    &.blue-theme {
      color: blue;
    }
  }
}

但是通过主题mixin这样做可能比较棘手。

看看CanColor类的想法:

https://github.com/angular/components/blob/8.1.x/src/material/core/common-behaviors/color.ts