Luego de mucho luchar hemos hallado el arreglo de este dilema que muchos los usuarios de nuestro espacio han tenido. Si quieres aportar alguna información no dejes de compartir tu conocimiento.
Solución:
¡Encontré una solución increíble! Estoy muy emocionado de mostrar esto porque me ha estado molestando sobre cómo implementarlo durante años. Así que aquí va; Primero, cambie todos sus archivos css a scss;
Para proyectos existentes
-
Ejecutar en consola
ng set defaults.styleExt=scss
(ng set parece haberse depreciado, pero puede consultar esto para obtener una solución gracias al usuario @wlyles get / set han quedado obsoletos en favor del comando config)
- Cambiar el nombre de todos los existentes
.css
archivos a.scss
- Cambie manualmente la extensión del archivo de
styles
en.angular-cli.json
de .css a.scss
- Si no utilizó una herramienta como WebStorm Refactor para cambiar el nombre, cambie manualmente todos los
styleUrls
de.css
para.scss
Para proyectos futuros
-
Solo para su nuevo proyecto, simplemente use
ng new your-project-name --style=scss
-
Para que todos los proyectos nuevos utilicen scss use
ng set defaults.styleExt=scss --global
Ahora necesitará tener un archivo theme.scss en la raíz de su aplicación así:
Ahora, en su archivo style.scss, desea agregar lo siguiente (como puede ver, hago referencia al color de fondo, pero puede cambiar esto a cualquier elemento del tema de su sitio como desee):
EDITAR: NO NECESITA poner este elemento @mixin personalizado en su styles.scss
puedes ponerlo en cualquiera de tus *name*.component.scss
y luego simplemente impórtelo e inclúyalo de la misma manera que lo hace con el ejemplo dado.
@import '[email protected]
/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);
Ahora ve a tu archivo theme.scss que usas para tematizar tus elementos de Material 2, si necesitas ayuda con la tematización, mira esto: Material 2 Github – Guía de temática
Ahora abra su theme.scss e importe su style.scss, ya que mi theme.scss está dentro de la raíz del /src/app/theme.scss
carpeta, primero debo salir de ella para hacer referencia a mi /src/styles.scss
archivo de estilo global como tal;
@import '../styles';
Entonces debemos incluir nuestra nueva costumbre @mixin
creamos en TODOS nuestros temas (si tiene varios como yo, por lo que cambia de color de acuerdo con el tema seleccionado actual).
Inclúyalo sobre el tema de material angular real, así:
@include theme-color-grabber($theme);
@include angular-material-theme($theme);
Si tiene algún tema como yo, agréguelo en la misma posición, así:
.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);
Puedes ver que agregué mi theme-color-grabber
por encima de la inclusión, realmente no importa si está por encima o por debajo del tema real porque está obteniendo los colores de los temas, que es el punto principal.
Todo mi themes.scss se ve así:
@import '[email protected]/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);
¡Y finalmente ahora podemos recurrir al color de nuestros temas para un fondo EN CUALQUIER LUGAR !, por ejemplo, doy un mat-grid-tile
el color ‘primario’ (no toma el argumento color = ”, como otros elementos como mat-toolbar) simplemente estableciendo su clase en el nombre de clase apropiado así:
EDITAR: En cada uno de los archivos scss de sus componentes, necesitará import '
para que su tema se aplique a ese componente. No importar theme.scss
en styles.scss
¡porque eso creará un bucle de importación!
Callum
Tech
Ambitious and ready to take on the world of Information Technology,
my love for programming and all things I.T. has not wavered since I first got access
to my fathers computer at age 9.
¡Finalmente nuestro resultado se verá así !:
Tema rojo activo
Tema azul activo
Yo personalmente puse esos en variables css4 para poder usarlos sin importaciones como tal
background: var(--color-primary)
Y aquí se explica cómo configurar las variables css4
@import '[email protected]/material/theming';
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$app-primary: mat-palette($mat-blue);
$app-accent: mat-palette($mat-orange);
$app-warn: mat-palette($mat-red);
$app-success: mat-palette($mat-light-green);
// Create the theme object (a Sass map containing all of the palettes).
$app-theme: mat-light-theme($app-primary, $app-accent, $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.
@include angular-material-theme($app-theme);
$primary: map-get($app-theme, primary);
$accent: map-get($app-theme, accent);
:root
--color-primary: #mat-color($app-primary);
--color-accent: #mat-color($app-accent);
--color-warn: #mat-color($app-warn);
--color-success: #mat-color($app-success);
ahora los colores se pueden usar en archivos css sin importar con
background: var(--color-primary)
ACTUALIZAR:
Aquí se publicó una nueva versión de esta solución:
https://github.com/mirismaili/angular-material-dynamic-themes
Si solo necesita la respuesta a la pregunta formulada, probablemente sea mejor consultar la primera versión de la respuesta, a continuación. Además, recomiendo leer esta sección de la documentación del repositorio anterior: Use temas materiales para otros elementos.
Pero si desea otras capacidades que ve en el video a continuación, le recomiendo este nuevo enfoque.
-
Demo en vivo:
https://stackblitz.com/github/mirismaili/AngularMaterialDynamicThemes
Gracias, StackBlitz
RESPUESTA ARCHIVADA:
stackblitz aquí
Partes más importantes:
En tus styles.scss
(o themes.scss
si usted tiene):
@import '[email protected]/material/theming';
@include mat-core();
@mixin define-css-classes($theme)
@include angular-material-theme($theme);
$primary: map-get($theme, primary);
$accent: map-get($theme, accent);
$warn: map-get($theme, warn);
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
// CSS THEME-DEPENDENT-STYLES ARE HERE:
.theme-dependent-colors
background: mat-color($primary);
color: mat-color($accent);
/**
* Define your custom themes in this map.
* The `key` of each member is the name of CSS class for that theme.
* To better understand the schema of the map, see `@each` loop below and especially pay attention to `map-has-key()` functions.
*/
$app-themes: (
indigo-pink : (primary-base: $mat-indigo, accent-base: $mat-pink),
deeppurple-amber: (primary-base: $mat-deep-purple, accent-base: $mat-amber),
pink-bluegrey : (primary-base: $mat-pink, accent-base: $mat-blue-gray, is-dark: true),
purple-green : (primary-base: $mat-purple, accent-base: $mat-green, is-dark: true),
);
@each $css-class, $theme in $app-themes
$primary: if(map-has-key($theme, primary), map-get($theme, primary), mat-palette(map-get($theme, primary-base)));
$accent: if(map-has-key($theme, accent), map-get($theme, accent), mat-palette(map-get($theme, accent-base)));
$warn: if(map-has-key($theme, warn), map-get($theme, warn), mat-palette(
if(map-has-key($theme, warn-base), map-get($theme, warn-base), $mat-red)
));
.#$css-class
@include define-css-classes(mat-light-theme($primary, $accent, $warn));
.#$css-class-dark
@include define-css-classes(mat-dark-theme($primary, $accent, $warn));
.theme-primary.#$css-class
background-color: mat-color($primary);
...
Cambio de tema dinámico, usando setTheme()
en mecanografiado (ver aquí y aquí):
import Component, HostBinding from '@angular/core';
import OverlayContainer from "@angular/cdk/overlay";
const THEME_DARKNESS_SUFFIX = `-dark`;
export class AppComponent
@HostBinding('class') activeThemeCssClass: string;
isThemeDark = false;
activeTheme: string;
setTheme(theme: string, darkness: boolean = null)
if (darkness === null)
darkness = this.isThemeDark;
else if (this.isThemeDark === darkness)
if (this.activeTheme === theme) return;
else
this.isThemeDark = darkness;
this.activeTheme = theme;
const cssClass = darkness === true ? theme + THEME_DARKNESS_SUFFIX : theme;
const classList = this.overlayContainer.getContainerElement().classList;
if (classList.contains(this.activeThemeCssClass))
classList.replace(this.activeThemeCssClass, cssClass);
else
classList.add(cssClass);
this.activeThemeCssClass = cssClass;
constructor(overlayContainer: OverlayContainer)
this.setThemeClass('indigo-pink', false); // Default theme
Vea otras cosas en stackblitz.
ADVERTENCIA: Agregar 8 temas de material dinámico a la aplicación (4 luces + 4 oscuras) aumentó el tamaño de la construcción styles.css
por ~420 kB
en mi caso (comparado con uno static tema material).
Si para ti ha sido útil nuestro artículo, sería de mucha ayuda si lo compartieras con otros programadores así nos ayudas a dar difusión a nuestro contenido.