web-dev-qa-db-fra.com

Obtenir la palette de couleurs du thème Matériau 2 pour les autres éléments

Je suis en train de construire une application, mais je souhaite conserver un jeu de couleurs cohérent qui peut être modifié avec les paramètres de manière à utiliser Matériau (2) avec angulaire (2+), mais je ne suis pas sûr de savoir comment obtenir le jeu de couleurs sur des éléments qui ne sont pas directement offre la possibilité de les colorer avec color="primary", donc il me reste à essayer de comprendre comment obtenir la couleur/le jeu de couleurs que mon thème Matériau 2 utilise . Et je veux que cela change lorsque le thème change, par exemple ma barre de navigation adapter au changement de thème parce que son ensemble à 

<mat-toolbar color="primary" class="fixed-navbar mat-elevation-z10">

Mais un élément de grille du matériau 2 ne prend pas le même argument, je suis donc obligé d'essayer de lui donner un style assez proche ou de ne pas le faire correspondre du tout (et il ne s'adaptera pas aux changements de thème), comme indiqué ici:

 enter image description here

Je veux qu'il corresponde à la couleur du tapis de thème, qui est ici (et est modifié pour les options sélectionnées dans les paramètres de la barre de navigation)

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

@include mat-core();



$candy-app-primary: mat-palette($mat-red);
$candy-app-accent:  mat-palette($mat-deep-orange, A200, A100, A400);
$candy-app-warn:    mat-palette($mat-red);
$candy-app-theme: mat-dark-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
.default {
  @include angular-material-theme($candy-app-theme);
}
.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include angular-material-theme($light-theme);
}
@include angular-material-theme($candy-app-theme);
11
Cacoon

J'ai trouvé un moyen génial de contourner le problème !!!! Je suis tellement excité de le montrer parce que cela me dérange de savoir comment le mettre en œuvre depuis des siècles ........ Alors, voilà; Tout d'abord, changez tous vos fichiers css à scss;

Pour les projets existants

  • Exécuter dans la console ng set defaults.styleExt=scss

  • Renommez tous les fichiers .css existants en .scss 

  • Modifiez manuellement l'extension de fichier de styles dans .angular-cli.json de .css à .scss
  • Si vous n'avez pas utilisé d'outil comme WebStorm Refactor pour renommer, modifiez manuellement tous les styleUrls de .css en .scss.

Pour les projets futurs

  • Juste pour votre nouveau projet, utilisez simplement ng new your-project-name --style=scss

  • Pour tous les nouveaux projets, utilisez scss, utilisez ng set defaults.styleExt=scss --global

Vous devez maintenant avoir un fichier theme.scss à la racine de votre application, comme suit:  where themes are

Maintenant, dans votre fichier style.scss, vous voulez ajouter ce qui suit (comme vous pouvez le voir, je fais référence à la couleur de fond, mais vous pouvez le changer en n’importe quel élément pour thématiser votre site à votre guise):

EDIT: Vous n'avez PAS BESOIN de mettre cet élément @mixin personnalisé dans votre styles.scss, vous pouvez le mettre dans n'importe lequel de vos *name*.component.scss, puis simplement l'importer et l'inclure de la même manière que dans l'exemple donné!

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

// Define a custom mixin that takes in the current theme
@mixin theme-color-grabber($theme) {
  // Parse the theme and create variables for each color in the pallete
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);
  // Create theme specfic styles
  .primaryColorBG {
    background-color: mat-color($primary);
  }
  .accentColorBG {
    background-color: mat-color($accent);
  }
  .warnColorBG {
    background-color: mat-color($warn);
  }
}

Allez maintenant dans votre fichier theme.scss que vous utilisez pour créer un thème pour vos éléments de Material 2, si vous avez besoin d’aide pour les thèmes suivants: Material 2 Github - Guide théming

Ouvrez maintenant votre theme.scss et importez votre style.scss car mon theme.scss se trouve à la racine du dossier /src/app/theme.scss. Je dois d'abord en sortir pour faire référence à mon fichier de style global /src/styles.scss comme so;

@import '../styles';

Ensuite, nous devons réellement inclure notre nouveau @mixin personnalisé que nous avons créé dans TOUS nos thèmes (si vous en avez plusieurs comme je le fais, la couleur change en fonction du thème sélectionné).

Incluez-le au-dessus du thème angular-material-theme actuel, comme suit: 

@include theme-color-grabber($theme);
@include angular-material-theme($theme);

Si vous avez des thèmes comme moi, ajoutez-les à la même position:

.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include theme-color-grabber($light-theme);
  @include angular-material-theme($light-theme);

}

Vous pouvez voir que j'ai ajouté mon theme-color-grabber au-dessus de l'inclinaison, peu importe si son thème est situé au-dessus ou au-dessous du thème réel, car il prend les couleurs du thème, ce qui est le point principal.

Tout mon themes.scss ressemble à ceci:

@import '~@angular/material/theming';
//We import our custom scss component here
@import '../styles';

@include mat-core();

$theme-primary: mat-palette($mat-red);
$theme-accent:  mat-palette($mat-deep-orange, A200, A100, A400);
$theme-warn:    mat-palette($mat-red);
$theme: mat-dark-theme($theme-primary, $theme-accent, $theme-warn);
//
@include theme-color-grabber($theme);
@include angular-material-theme($theme);
.light {
  $light-primary: mat-palette($mat-blue, 200,300, 900);
  $light-accent:  mat-palette($mat-light-blue, 600, 100, 800);
  $light-warn:    mat-palette($mat-red, 600);
  $light-theme: mat-dark-theme($light-primary, $light-accent, $light-warn);
  @include theme-color-grabber($light-theme);
  @include angular-material-theme($light-theme);

}

Et enfin, nous pouvons maintenant faire appel à la couleur de nos thèmes pour un arrière-plan ANYWHERE !, par exemple, je donne au code mat-grid-tile la couleur 'primaire' (il ne prend pas l'argument color = '', comme d'autres éléments tels que mat-toolbar) en il suffit de définir sa classe sur le nom de classe approprié comme ceci:

EDIT: Dans chacun de vos fichiers scss de composants, vous aurez besoin de import '<path-to>/theme.scss' pour que votre thème puisse s'appliquer à ce composant. N'importez pas theme.scss dans styles.scss car cela créerait une boucle d'importation!

<mat-grid-list cols="4" rows="4" rowHeight="100px">
  <mat-grid-tile
    colspan="4"
    rowspan="5"
  class="primaryColorBG">
    <div fxLayout="column" fxLayoutAlign="center center">
      <h1 class="title-font">Callum</h1>
      <h1 class="title-font">Tech</h1>
    </div>
    <p>
      Ambitious and ready to take on the world of Information Technology,<br>
      my love for programming and all things I.T. has not wavered since I first got access<br>
      to my fathers computer at age 9.
    </p>
  </mat-grid-tile>

</mat-grid-list>

Enfin, notre résultat ressemblera à ceci !:

Thème rouge actif Red theme

Thème bleu actif enter image description here

23
Cacoon
  1. Définissez la règle des styles d'application sur SASS:
    La mise à jour du thème des composants personnalisés au moment de l'exécution nécessite l'utilisation de @mixin; par conséquent, vos règles de style d'application doivent être SASS (pas CSS) . Vous pouvez lire ici la procédure de configuration de Angular-Cli avec SASS. : https://scotch.io/tutorials/using-sass-with-the-angular-cli

  2. Définissez @mixin pour le composant personnalisé:
    Dans chaque composant utilisant des couleurs de thème, créez un @mixin dans son fichier .scss. Pour ce composant, extraire toute la définition de couleur. Et déplacez-les dans le @mixin, comme ceci:

// --- file: my-component_1.scss ---
@import '~@angular/material/theming'; // we need to add this so we could use Material functions
@mixin set-theme-component-1($theme)
{
  // Extract whichever individual palettes you need from the theme.
  $primary-palette: map-get($theme, primary);
  $accent-palette:  map-get($theme, accent);
  $warn-palette:    map-get($theme, warn);

  .component-container
  {
    background-color: mat-color($primary-palette); // use the mat-color function to extract the color from the palette
    border-color: mat-color($warn-palette);
  }
}

// Style rules that aren't theme/color related (size, font, etc)
.component-container
{
  width: 100%;
  ...
}
  1. Définir un fichier de thèmes:
    Vous devrez définir un fichier de thèmes (si vous ne l’avez pas déjà fait) et appeler le @mixins défini dans ce fichier, comme suit:
// --- file: app.theme.scss ---
@import '~@angular/material/theming';
@include mat-core(); // include this only once in your code!!!

// each custom component that uses theme colors will be imported here - we need there @mixin
@import './some-path/some-folder/my-component_1'; // no need to specify .scss suffix

@mixin set-theme($theme) // define a new @mixin that will be invoked each time the theme is changed
{
  @include set-theme-component-1($theme); // invoke the mixin we defined for component_1
  // repeat this for each component that uses theme colors
}

// define your themes:
.theme-light
{
  $light-primary: mat-palette($mat-Indigo);
  $light-accent:  mat-palette($mat-pink, A200, A100, A400);
  $light-warn:    mat-palette($mat-red);
  $light-theme:   mat-light-theme($light-primary, $light-accent, $light-warn);

  @include angular-material-theme($light-theme);
  @include set-theme($light-theme); // once the theme was set, invoke the mixin
}

.theme-dark
{
  $dark-primary:  mat-palette($mat-teal, A400);
  $dark-accent:   mat-palette($mat-grey, 800);
  $dark-warn:     mat-palette($mat-red, 700);
  $dark-theme:    mat-dark-theme($dark-primary, $dark-accent, $dark-warn);

  @include angular-material-theme($dark-theme);
  @include set-theme($dark-theme); // once the theme was set, invoke the mixin
}

C'est ça :-)

Ce sont quelques étapes supplémentaires que vous devez implémenter afin de fonctionner correctement (elles ne sont pas liées à des composants personnalisés, donc je ne ferai que les jeter rapidement).
- Créez un service de thème qui enregistrera le thème actuel. Ce service devra mettre à jour le OverlayContainer (le matériau angulaire utilise ce conteneur pour l’arrière-plan des modaux tels que les fenêtres contextuelles et les listes déroulantes).
- Ajoutez la classe de thème (theme-dark ou autre) à l'un des éléments racine du DOM.
- Ajoutez la classe mat-app-background à l'un des éléments racine du DOM. Cela changera la couleur de fond et la couleur de la police en fonction du thème.
- Pour une meilleure conception logicielle - si vous avez beaucoup de thèmes, la scission du fichier de thème peut être une bonne idée pour les marsouins de maintenance.

Vous pouvez continuer à lire ici: https://material.angular.io/guide/theming

ou voir le projet Github: https://github.com/angular/material2/blob/master/src/lib/core/theming/_theming.scss

0
Gil Epshtain

Je suis un débutant absolu et c’est peut-être un exemple de bonnes pratiques, inutile pour ce cas ou une solution consommatrice de ressources, mais à myangularthemefile.scss , j’avais créé ces classes:

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

...

.matcolorprimary{
    color: mat-color($mitjans-primary)
}

.matcoloraccent {
    color: mat-color($mitjans-accent);
}

.matcolorwarn {
    color: mat-color($mitjans-warn);
}

Et je les ajoute aux éléments HTML dont j'ai besoin dans le modèle du composant.

Je suppose qu'il serait facile de créer la même structure pour les couleurs de fond ...

Cela pourrait-il être une alternative à l'inclusion d'artefacts sass dans chaque feuille de style de composant ombre dom pour les petits projets?

0
Josep Alacid