Angular Material - 全局颜色变量 [英] Angular Material - Global color variables

查看:83
本文介绍了Angular Material - 全局颜色变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看 Angular Material 文档,他们建议对每个组件使用 -theme 文件来管理将任何与主题相关的样式应用于特定类.

从我的角度来看,这种方法的一些缺点是:

  • 相当冗长
  • 将样式拆分为两个不同的位置
  • 您的所有前端开发人员都需要了解 Angular Material 颜色的工作原理
  • 使更改值变得更加困难(例如,我们可能一直在使用 mat-color($primary, 200) 作为边框颜色,现在想将其更改为 mat-color($primary, 300).这将在整个代码库中重复.

如果采用一致的设计语言,则只会使用一部分颜色(例如,主调色板中的 4 种颜色、重点调色板中的 3 种颜色、几种不同的前景色/背景色等).

鉴于上述情况,使用 _colors.scss 定义使用主题的确切颜色而不是希望开发人员每次都从主题中提取正确的值不是更有意义吗?

例如也许是这样的:

 $clr-primary-default: mat-color($primary);$clr-primary-contrast: mat-color($primary, default-contrast);$clr-primary-light: mat-color($primary, light);$clr-primary-dark: mat-color($primary, darker);$clr-accent-default: mat-color($accent);$clr-accent-light: mat-color($accent, light);$clr-accent-dark: mat-color($accent, darker);$clr-default-text: mat-color($foreground);$clr-secondary-text: mat-color($foreground, secondary-text);//等等

然后不是为每个需要特定颜色的组件创建一个单独的 -theme 文件,我可以简单地导入 colors.scss 文件并直接在*.component.scss 文件.

只是想验证上述内容是否合理,并且我没有遗漏任何明显会导致赛道痛苦的事情?

另一个棘手的部分是如何在单独的 colors 文件中有效地实际定义这些文件,因为该文件需要访问主题数据.

解决方案

为什么要使用@mixin?

<块引用>

只是想验证上述内容是否合理,并且我没有遗漏任何明显会导致赛道痛苦的事情?

我唯一能想到的是,您会错过在一个应用程序中使用多个主题的机会.使用 Angular Material 文档中的方法,您将为每个组件都有一个 @mixin,您可以使用不同的 $theme 变量多次@include.

来自 https://medium.com 的示例/@tomastrajan/the-complete-guide-to-angular-material-themes-4d165a9d24d1:

.default-theme {@include angular-material-theme($theme);@include custom-component-theme($theme);}.light 主题{@include angular-material-theme($light-theme);@include custom-component-theme($light-theme);}

如果您将颜色作为 scss 变量导入到您的组件中并在那里使用它,这将不起作用.

单独的颜色文件

<块引用>

另一个棘手的部分是如何在单独的颜色文件中有效地实际定义这些文件,因为该文件需要访问主题数据.

这实际上非常简单:我有一个单独的文件 src/styles/_variables.scss,其中包含我的自定义颜色作为 scss 变量和 $theme 变量,我稍后在 src/theme.scss 中使用.

@import '~@angular/material/theming';//主题配置$primary: mat-palette($mat-blue, 800, 500, 900);$accent: mat-palette($mat-blue, A200, A100, A400);$warn: mat-palette($mat-red);$theme: mat-light-theme($primary, $accent, $warn);//自定义颜色$自定义颜色:(custom-color-a: mat-color($mat-green, 700),custom-color-b: mat-color($mat-red, 400),);$theme: map-merge($theme, (custom-colors: $custom-colors));

要在组件中导入我的 _variables.scss,我必须stylePreprocessorOptions 添加到 angular.json 文件:

"styles": ["src/styles.scss",源代码/主题.scss"],样式预处理器选项":{包含路径":[源代码/样式"]},

现在我可以在我的组件的所有 scss 文件中导入我的变量:

@import '变量';.custom-class-a {背景色:map-get($custom-colors, custom-color-a);颜色:map-get($custom-colors, custom-color-b);}

为什么我使用 sass-mapmap-merge?

如您所见,我在 sass-map $custom-colors 中收集自定义颜色并将它们合并到我的 $theme 变量中.通过这种方式,我可以通过直接将自定义颜色导入到我的组件样式表中来使用它(如上所述)或者我可以在我的组件中使用它们@mixin在 Angular Material 文档中进行了描述.

@import '~@angular/material/theming';@mixin custom-component-theme($theme) {$custom-colors: map-get($theme, custom-colors);.custom-class-a {背景色:map-get($custom-colors, custom-color-a);颜色:map-get($custom-colors, custom-color-b);}}

也许这种组合是您的前端开发人员可以使用的一种方式?

Looking at the Angular Material documentation, they recommend using a -theme file per component to manage applying any theme-related styles to a specific class.

From my perspective, some downsides to this approach are:

  • quite verbose
  • splits up the style into two different locations
  • all your frontend devs need to understand how Angular Material colours work
  • makes it harder to change values (e.g. we might've been using mat-color($primary, 200) for border colours and now want to change it to mat-color($primary, 300). This will have been repeated all throughout the codebase.

Given a consistent design language, there will only be a subset of colors that will be used (e.g. 4 colors from the primary palette, 3 from the accent palette, a few different foreground / background colors, etc).

Given the above, doesn't it make more sense to have a _colors.scss that defines the exact colors using the theme rather than hoping developers extract the correct value from the theme each time?

e.g. maybe something like:

  $clr-primary-default: mat-color($primary);
  $clr-primary-contrast: mat-color($primary, default-contrast);
  $clr-primary-light: mat-color($primary, lighter);
  $clr-primary-dark: mat-color($primary, darker);

  $clr-accent-default: mat-color($accent);
  $clr-accent-light: mat-color($accent, lighter);
  $clr-accent-dark: mat-color($accent, darker);

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

  //etc

Then rather than creating a separate -theme file for each component that requires specific colors, I can simply import the colors.scss file and use the variables directly in the *.component.scss file.

Just wanting to validate that the above is sound and that I'm not missing anything obvious that's going to cause pain down the track?

The other tricky part is how to actually define these in a separate colors file efficiently given the file will need access to the theme data.

解决方案

Why use @mixin?

Just wanting to validate that the above is sound and that I'm not missing anything obvious that's going to cause pain down the track?

The only thing, I can think of, is that you would miss the opportunity to use multiple themes in one application. With the approach from the Angular Material documentation, you would have a @mixin for each component, that you can @include multiple times with different $theme variables.

Example from https://medium.com/@tomastrajan/the-complete-guide-to-angular-material-themes-4d165a9d24d1:

.default-theme {
  @include angular-material-theme($theme);
  @include custom-component-theme($theme);
}

.light-theme {
  @include angular-material-theme($light-theme);
  @include custom-component-theme($light-theme);
}

This wouldn't work, if you import colors as scss-variables into your components and use it there.

Separate file for colors

The other tricky part is how to actually define these in a separate colors file efficiently given the file will need access to the theme data.

This is actually pretty straight forward: I have a separate file src/styles/_variables.scss that contains my custom colors as scss-variables and also the $theme variable, that I am using later in src/theme.scss.

@import '~@angular/material/theming';
// Theme configuration
$primary: mat-palette($mat-blue, 800, 500, 900);
$accent:  mat-palette($mat-blue, A200, A100, A400);
$warn: mat-palette($mat-red);

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

// Custom colors
$custom-colors: (
  custom-color-a: mat-color($mat-green, 700),
  custom-color-b: mat-color($mat-red, 400),
);
$theme: map-merge($theme, (custom-colors: $custom-colors));

To import my _variables.scss inside a component, I have to add stylePreprocessorOptions to the angular.json file:

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

Now I can import my variables in all scss-files of my components:

@import 'variables';

.custom-class-a {
  background-color: map-get($custom-colors, custom-color-a);
  color: map-get($custom-colors, custom-color-b);
}

Why do I use a sass-map and map-merge?

As you noticed, I collect my custom colors in the sass-map $custom-colors and merge them into my $theme variable. This way I could either use my custom colors by directly importing it into my components style sheet (as described above) or I could use them inside my components @mixin the way it is described in the Angular Material documentation.

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

@mixin custom-component-theme($theme) {
  $custom-colors: map-get($theme, custom-colors);

  .custom-class-a {
    background-color: map-get($custom-colors, custom-color-a);
    color: map-get($custom-colors, custom-color-b);
  }
}

Maybe this combination is a way that your frontend devs could work with?

这篇关于Angular Material - 全局颜色变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆