En consultant la documentation Angular Material), ils recommandent d'utiliser un fichier -theme
Par composant pour gérer l'application de styles liés à un thème à une classe spécifique.
De mon point de vue, certains inconvénients de cette approche sont:
mat-color($primary, 200)
pour les couleurs de bordure et voulons maintenant le changer en mat-color($primary, 300)
. Cela aura été répété tout au long de la base de code.Étant donné un langage de conception cohérent, il n'y aura qu'un sous-ensemble de couleurs qui sera utilisé (par exemple 4 couleurs de la palette principale, 3 de la palette d'accent, quelques couleurs différentes de premier plan/arrière-plan, etc.).
Compte tenu de ce qui précède, n'est-il pas plus logique d'avoir un _colors.scss
Qui définit les couleurs exactes en utilisant le thème plutôt que d'espérer que les développeurs extraient la valeur correcte du thème à chaque fois?
par exemple. peut-être quelque chose comme:
$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
Ensuite, plutôt que de créer un fichier -theme
Distinct pour chaque composant nécessitant des couleurs spécifiques, je peux simplement importer le fichier colors.scss
Et utiliser les variables directement dans le fichier *.component.scss
.
Je veux juste valider que ce qui précède est bon et que je ne manque rien d'évident qui va causer de la douleur sur la piste?
L'autre partie délicate est de savoir comment les définir réellement dans un fichier colors
séparé efficacement étant donné que le fichier aura besoin d'accéder aux données du thème.
@mixin
?Je veux juste valider que ce qui précède est bon et que je ne manque rien d'évident qui va causer de la douleur sur la piste?
La seule chose, je peux penser, est que vous manquez l'occasion d'utiliser plusieurs thèmes dans une seule application. Avec l'approche de la documentation des matériaux angulaires , vous auriez un @mixin
pour chaque composant, que vous pouvez @include
plusieurs fois avec différents $theme
variables.
Exemple de 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);
}
Cela ne fonctionnerait pas si vous importez des couleurs en tant que variables scss dans vos composants et les utilisiez là.
L'autre partie délicate est de savoir comment les définir efficacement dans un fichier de couleurs distinct, étant donné que le fichier aura besoin d'accéder aux données du thème.
C'est en fait assez simple: j'ai un fichier séparé src/styles/_variables.scss
qui contient mes couleurs personnalisées en tant que variables scss et également le $theme
variable, que j'utiliserai plus tard dans 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));
Pour importer mon _variables.scss
à l'intérieur d'un composant, je dois ajouter stylePreprocessorOptions
au angular.json
fichier :
"styles": [
"src/styles.scss",
"src/theme.scss"
],
"stylePreprocessorOptions": {
"includePaths": [
"src/styles"
]
},
Maintenant, je peux importer mes variables dans tous les fichiers scss de mes composants:
@import 'variables';
.custom-class-a {
background-color: map-get($custom-colors, custom-color-a);
color: map-get($custom-colors, custom-color-b);
}
map-merge
?Comme vous l'avez remarqué, je rassemble mes couleurs personnalisées dans la sass-map $custom-colors
et les fusionner dans mon $theme
variable. De cette façon, je pouvais utiliser mes couleurs personnalisées en les important directement dans la feuille de style de mes composants (comme décrit ci-dessus) ou je pouvais les utiliser dans mes composants @mixin
la manière dont il est décrit dans la documentation Angular Material).
@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);
}
}
Peut-être que cette combinaison est un moyen avec lequel vos développeurs frontaux pourraient travailler?
Je travaille sur un projet où j'ai utilisé les thèmes Material 2 et j'ai utilisé cette approche où j'utilise le nom de la classe et j'ajoute la classe de couleurs à l'échelle mondiale.
C'est ce que j'ai fait :
FileName: mytheme-sidemenu.scss:
// Import all the tools needed to customize the theme and extract parts of it
@import "~@angular/material/theming";
// Define a mixin that accepts a theme and outputs the color styles for the component.
@mixin mytheme-sidemenu($theme) {
// Extract whichever individual palettes you need from the theme.
$primary: map-get($theme, primary);
$accent: map-get(
$theme,
accent
); // Use mat-color to extract individual colors from a palette as necessary.
.col-primary {
color: mat-color($primary, 500) !important;
}
.col-accent {
color: mat-color($accent, 300) !important;
}
}
Voici mon fichier de thème principal: mytheme-theme.scss:
@import '~@angular/material/theming';
@import './variables/helper.scss';
@import './variables/spacemanager.scss';
@import './mytheme-sidemenu.scss';
// Primary theme
@include mat-core();
$mytheme-app-primary: mat-palette($mat-light-blue, 700, 600);
$mytheme-app-accent: mat-palette($mat-pink, A200, 900, A100);
$mytheme-app-warn: mat-palette($mat-deep-orange);
$mytheme-app-theme: mat-light-theme($mytheme-app-primary, $mytheme-app-accent, $mytheme-app-warn);
@include angular-material-theme($mytheme-app-theme);
// Secondary Theme
.mytheme-alt-theme {
$mytheme-alt-primary: mat-palette($mat-blue-grey, 500);
$mytheme-alt-accent: mat-palette($mat-pink, 500);
$mytheme-alt-warn: mat-palette($mat-deep-orange);
$mytheme-alt-theme: mat-light-theme($mytheme-alt-primary, $mytheme-alt-accent, $mytheme-alt-warn);
@include angular-material-theme($mytheme-alt-theme);
}
// Using the $theme variable from the pre-built theme you can call the theming function
@include mytheme-sidemenu($mytheme-app-theme);
et dans app.module.ts mettez à jour ceci:
export class AppModule {
constructor(
@Inject(OverlayContainer) private overlayContainer: OverlayContainer
) {
this.overlayContainer
.getContainerElement()
.classList.add("mytheme-alt-theme"); // this for double theme add to the root css class
}
}
J'ai défini les couleurs primaires, d'accentuation et d'avertissement en tant que variables personnalisées css dans le fichier styles.css comme suit:
@import "~@angular/material/theming";
@include mat-core();
$my-primary: mat-palette($mat-blue-grey);
$my-accent: mat-palette($mat-amber, A200, A100, A400);
$my-warn: mat-palette($mat-deep-orange);
$my-2-primary: mat-palette($mat-pink, 400, 200, 600);
$my-2-accent: mat-palette($mat-blue, A200, A100, A400);
$my-2-warn: mat-palette($mat-deep-orange, 500, 300, 700);
.dark-theme {
$my-theme-dark: mat-dark-theme($my-primary, $my-accent, $my-warn);
@include angular-material-theme($my-theme-dark);
$primary: mat-color($my-primary);
$accent: mat-color($my-accent);
$warn: mat-color($my-warn);
$fg_palette:map-get($my-theme-dark, foreground);
$bg_palette:map-get($my-theme-dark, background);
$fg:map-get($fg_palette, text);
$bg:map-get($bg_palette, background);
--primary: #{$primary};
--accent: #{$accent};
--warn: #{$warn};
--fg: #{$fg};
--bg: #{$bg};
}
.dark-theme-2 {
$my-2-theme-dark: mat-dark-theme($my-2-primary, $my-2-accent, $my-2-warn);
@include angular-material-theme($my-2-theme-dark);
$primary: mat-color($my-2-primary);
$accent: mat-color($my-2-accent);
$warn: mat-color($my-2-warn);
$fg_palette:map-get($my-2-theme-dark, foreground);
$bg_palette:map-get($my-2-theme-dark, background);
$fg:map-get($fg_palette, text);
$bg:map-get($bg_palette, background);
--primary: #{$primary};
--accent: #{$accent};
--warn: #{$warn};
--fg: #{$fg};
--bg: #{$bg};
}
Et utilisé ces variables dans l'un de mes composants comme ceci :( dans my-custom-component.scss)
.some-class {
color: var(--primary)
}
.another-class {
background-color: var(--bg)
}
.yet-another-class {
border-color: var(--accent)
}
En faisant comme ça, je peux changer n'importe quelle valeur liée à la couleur dans n'importe quel composant, car ces variables sont globales (définies dans styles.css) Lorsque je change de thème, ces couleurs changent également en fonction de la couleur du nouveau thème