Angular 材质自定义组件主题

Posted

技术标签:

【中文标题】Angular 材质自定义组件主题【英文标题】:Angular Material Custom Component Theming 【发布时间】:2018-10-08 19:21:22 【问题描述】:

我正在尝试将自定义 Angular Material 主题中自定义调色板中的颜色用于其他一些组件。

例如一个带有 mat-toolbar 的 div 和一个带有边距的图标,应该用主背景颜色填充。

关于主题的 Angular Material 指南说:

不应将主题文件导入其他 SCSS 文件。这将导致重复的样式被写入您的 CSS 输出。

但在组件主题指南中,它说如下:

您可以使用来自@angular/material/theming 的主题函数和材质调色板变量。您可以使用 mat-color 函数从调色板中提取特定颜色。例如:

// 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');

主题在组件中再次导入,他们从材料主题中提取颜色与功能。

我很困惑,在没有颜色输入的非角度材质组件或事件材质组件上使用颜色的正确方法是什么?

【问题讨论】:

你有没有得到这个问题的解决方案? 很遗憾没有。必须使用 css 类创建解决方法。 【参考方案1】:

我在this stack overflow answer 中描述了它。

您应该将主题相关变量和主题创建放在单独的文件中:

styles/_variables.scss 可以在所有组件scss文件中导入 使用 @import '~@angular/material/theming'; 使特定于材质的 mixin 可用 包含典型的主题变量,如$primary$accent$warn 包含一个或多个$theme 变量(例如通过mat-light-theme($primary, $accent, $warn);

theme.scss

应该导入其他任何地方

包括 Angular Material 核心和主题

@import 'variables';
@include mat-core();
@include angular-material-theme($theme);

要轻松地将styles/_variables.scss 导入到您的组件样式中,您必须使用add stylePreprocessorOptions to the angular.json file:

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

现在您可以在组件中导入自定义变量和主题变量,还可以使用特定于材质的 mixin,例如 mat-color

@import 'variables';

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

.custom-class-a 
  background-color: mat-color($background, card);
  color: mat-color($mat-green, 700);

【讨论】:

最后,我是这样做的,但对我来说,这更像是一种解决方法。但是谢谢你的回答。我会将其标记为已解决,因为(可悲)似乎没有更好的解决方案。 非常感谢您的回答!!!试图通过他们提供的文档找到一种方法来获取背景颜色实际上是不可能的。没有意识到您必须将背景颜色设置为 mat-color($background, card);我以为这只是 mat-color($background)。谢谢你救了我。【参考方案2】:

回答这个问题已经很晚了,但我遇到了同样的问题,并且花了很多时间试图弄清楚它是如何工作的。主要问题是:

The Angular Material documentation 定制自己的组件并不能告诉你整个故事,正如弗洛里安在他的问题中所说的那样。 我没有在在线讨论中找到一个示例,其中包含所有所需的文件和更改以使其正常工作。

我在 Stackblitz 上找到了两个有用的示例:

This one 展示了如何操作主题中的背景和前景元素。 This one 展示了如何在自定义主题之间切换。

但是,我需要一些不同的东西:

我想使用自己的颜色。 我想在 h1 或 div 等元素上的自己的组件中使用它们。 当然,我想避免重复样式,这是推荐但未在 Angular Material 主题文档中解释的。

This post on GitHub 对我帮助最大。 This discussion 在从 CSS 切换到 SCSS 方面也很有帮助。

对于遇到相同问题的任何人,我想分享我的解决方案,以便您在一处获得所有信息:

1.获取您的颜色定义

假设您想使用#3F51B5 作为主要颜色,而另一种作为强调色。转到this site,输入每种颜色并下载定义(选择“Angular JS 2 (Material 2)”并复制$md-mcgpalette0: (___) 的内容。

2。创建theme_variables.scss并将其放入您的src目录中。

插入您刚刚下载的颜色定义。

@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);

您也可以将调色板与变量定义分开到两个不同的文件中,但我就这样离开了。

3.创建theme.scss并将其放在你的src目录中:

@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.创建styles.scss并将其放在你的src目录中:

@import "./theme.scss";

// add the rest of your global styles

5.更新angular.json

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

6.在您想要使用主题颜色的组件中,将 example.component.css-file 重命名为 .scss 并对其进行编辑:

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

h1  
    color: $primary;


h2  
    color: $accent;

// put the rest of your styling

7.更新 example.component.ts 文件中的样式 url:

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

8.默认切换到scss

运行ng config schematics.@schematics/angular:component.styleext scss 为以后的新组件创建scss文件。

更新:如果在创建组件时仍然没有创建 scss 文件,原因可能是您必须为所有项目配置 scss 扩展。请参阅this discussion 了解更多信息。对我有什么帮助:ng config projects.&lt;projectname&gt;.schematics.@schematics/angular:component.style scss


如果您不需要所有组件中的变量,您可以这样保留它们的 css 文件。每当您想在组件中使用主题颜色时,将 css 文件更改为 scss,导入主题变量并更新组件中的 styleUrl(步骤 6 + 7)。

我对 Angular 还是很陌生,可能有些事情你可以做得更好。因此,任何人有进一步的建议,请告诉我。

【讨论】:

以上是关于Angular 材质自定义组件主题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 angular5 和 angular 材质创建自定义颜色主题

创建自定义角度材质主题时最好的方法是啥?

Angular - 材质:进度条自定义颜色?

Angular Material 主题系统-- 自定义主题

Material design 2 自定义css组件

Angular 材质中具有错误验证的 ControlValueAccessor