问题
theme-variables.scss
//---------------------------------------------------------
//Declare a global variable and set it to red color
//---------------------------------------------------------
$fg-primary-text: red;
//---------------------------------------------------------
//below @mixin is used in styles.scss to pass the custom-theme
//---------------------------------------------------------
@mixin cache-theme-colors($theme) {
@include set-global-variables($theme);
}
//---------------------------------------------------------
//local mixin to set the global-variable from the $theme using !global flag
//---------------------------------------------------------
@mixin set-global-variables($theme: $theme, $fg-primary-text: $fg-primary-text) {
$foreground: map-get($theme, foreground); //get foreground from the theme
$fg-primary-text: mat-color($foreground, text) !global; //get the text color from the theme and set it here using the !global flag
}
component.scss
@import "../../../../assets/themes/theme-variables.scss";
.text-color {
color: $fg-primary-text; //use the variable (but it is still red)
}
But the color is still red My question is: how to set the global variable in scss and change it inside a mixin/function and use it in any component.scss
回答1:
You will need a mixin function in your component.scss.
And then have a @include in your main.scss file.
component.scss
@mixin text-color-mixin($theme) {
$is-dark-theme: map-get($theme, is-dark);
.text-color {
color: if($is-dark-theme, red, blue);
}
}
main.scss
@import ..<path to file>.../component.scss
...
<Other code>
...
@include text-color-mixin($theme);
To find out more on how you can structure your angular project themes you can look at https://github.com/angular/material.angular.io
This is the official repo for the angular material io documentation site.
EDIT
I think this also answers your question
How to manipulate scss variables in Angular2 components
回答2:
Atlast I've found a solution, and I'm sharing here for those who need it.
Note: I know it's very long.. but read patiently you may get something or correct me If I'm doing anything wrong.
First start from the theme.service
theme.service.ts
import { Injectable } from '@angular/core';
import { OverlayContainer } from '@angular/cdk/overlay';
@Injectable({ providedIn: 'root' })
export class ThemeService {
constructor(private overlayContainer: OverlayContainer) {}
currentThemeNAME: string = "light-theme";
//DEFAULT_THEME
private defaultThemeNAME: string = "light-theme";
setDefaultTHEME() {
this.setTHEME(this.defaultThemeNAME);
}
//LIGHT_THEME
private lightThemeNAME: string = "light-theme";
setLightTHEME() {
this.setTHEME(this.lightThemeNAME);
}
//DARK_THEME
private darkThemeNAME: string = "dark-theme";
setDarkTHEME() {
this.setTHEME(this.darkThemeNAME);
}
//TO_SET_THE_THEME
setTHEME(themeNAME: string) {
console.log(themeNAME);
this.currentThemeNAME = themeNAME;
this.overlayContainer.getContainerElement().classList.add(this.currentThemeNAME);
}
//TO_CYCLE_THE_THEME
cycleTHEME() {
switch (this.currentThemeNAME) {
case this.lightThemeNAME:
this.setDarkTHEME();
break;
case this.darkThemeNAME:
this.setLightTHEME();
break;
}
}
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { FlexLayoutModule } from '@angular/flex-layout';
//CORE-SERVICES
import { ThemeService } from './core/services/theme.service';
@NgModule({
entryComponents: [...],
declarations: [...],
exports: [...],
imports: [...],
providers: [ ThemeService ], //<----Important
bootstrap: [AppComponent],
})
export class AppModule {
//important
constructor(private themeSRVC: ThemeService) {
this.themeSRVC.setDefaultTHEME(); //<----Important
}
}
Lets Assume I've 2 themes:
1) light-theme.scss
// define 3 theme color
// mat-palette accepts $palette-name, default, lighter and darker variants
$light-theme-primary: mat-palette($mat-grey, 500, 100, 700);
$light-theme-accent: mat-palette($mat-pink);
$light-theme-warn: mat-palette($mat-red);
// create theme (use mat-dark-theme for themes with dark backgrounds)
$light-theme: mat-light-theme( $light-theme-primary, $light-theme-accent, $light-theme-warn);
2) dark-theme.scss
// define 3 theme color
// mat-palette accepts $palette-name, default, lighter and darker variants
$dark-theme-primary: mat-palette($mat-grey, 900, 700, 900);
$dark-theme-accent: mat-palette($mat-blue-grey);
$dark-theme-warn: mat-palette($mat-red);
// create theme (use mat-dark-theme for themes with dark backgrounds)
$dark-theme: mat-dark-theme($dark-theme-primary, $dark-theme-accent, $dark-theme-warn);
styles.scss
/* You can add global styles to this file, and also import other style files */
@import './assets/fonts/roboto/stylesheet.css';
@import './assets/icons/material-icons/v42/stylesheet.css';
//important
@import '~@angular/material/theming';
//important: always include only once per project
@include mat-core();
//important: import our custom theme files here
@import './assets/themes/light-theme.scss';
@import './assets/themes/dark-theme.scss';
//important: import the theme cacher
@import './assets/themes/register_components.scss';
html,
body {
height: 100%;
padding: 0px;
margin: 0px;
font-family: Roboto;
}
// to set this theme:
// set yout component's root element's class
// example-1: <body class="dark-theme"> ... </body>
// example-2: <form [ngClass]="themeSRVC.currentThemeNAME"
.light-theme {
@include angular-material-theme($light-theme); //set material_theme
@include set-components-theme($light-theme); //cache_theme
}
// to set this theme:
// set yout component's root element's class
// example-1: <body class="dark-theme"> ... </body>
// example-2: <form [ngClass]="themeSRVC.currentThemeNAME"
.dark-theme {
@include angular-material-theme($dark-theme); //set material_theme
@include set-components-theme($dark-theme); //cache_theme
}
//...similarly register your other themes here
register_components.scss
@import '~@angular/material/theming';
@import '../src/app/erp/security/erp-login/erp-login.component.scss';
@import '../src/app/erp/dashboard/dashboard.component.scss';
@mixin set-components-theme($theme) {
//###################################################################################
//---STEP-(1/3): EXTRACT_PALLETE_AND_COLORS----------
//https://github.com/angular/material2/blob/master/src/lib/core/theming/_palette.scss
//https://github.com/angular/material2/blob/master/src/lib/core/ripple/_ripple.scss
//###################################################################################
//---01-PRIMARY---------------------
$primary-palette: map-get($theme, primary); //<---
$primary-color: mat-color($primary-palette, default);
$primary-light: mat-color($primary-palette, lighter);
$primary-dark: mat-color($primary-palette, darker); //<---
//---02-ACCENT----------------------
$accent-palette: map-get($theme, accent); //<---
$accent-color: mat-color($accent-palette, default);
$accent-light: mat-color($accent-palette, lighter);
$accent-dark: mat-color($accent-palette, darker); //<---
//---03-WARN------------------------
$warn-palette: map-get($theme, warn); //<---
$warn-color: mat-color($warn-palette, default);
$warn-light: mat-color($warn-palette, lighter);
$warn-dark: mat-color($warn-palette, darker); //<---
//---04-FOREGROUND------------------
$foreground-palette: map-get($theme, foreground); //<---
$fg-base: mat-color($foreground-palette, base); //full_black or full_white
$fg-primary-text: mat-color($foreground-palette, text);
$fg-secondary-text: mat-color($foreground-palette, secondary-text);
$fg-hint-text: mat-color($foreground-palette, hint-text);
$fg-disabled: mat-color($foreground-palette, disabled);
$fg-disabled-button: mat-color($foreground-palette, disabled-button);
$fg-disabled-text: mat-color($foreground-palette, disabled-text);
$fg-divider: mat-color($foreground-palette, divider);
$fg-dividers: mat-color($foreground-palette, dividers);
$fg-elevation: mat-color($foreground-palette, elevation);
$fg-icon: mat-color($foreground-palette, icon);
$fg-icons: mat-color($foreground-palette, icons);
$fg-slider-min: mat-color($foreground-palette, slider-min);
$fg-slider-off: mat-color($foreground-palette, slider-off);
$fg-slider-off-active: mat-color($foreground-palette, slider-off-active); //<--
//---05-BACKGROUND------------------
$background-palette: map-get($theme, background); //<---
$bg-color: mat-color($background-palette, background);
$bg-status-bar: mat-color($background-palette, status-bar);
$bg-app-bar: mat-color($background-palette, app-bar);
$bg-hover: mat-color($background-palette, hover);
$bg-card: mat-color($background-palette, card);
$bg-dialog: mat-color($background-palette, dialog);
$bg-disabled-button: mat-color($background-palette, disabled-button);
$bg-raised-button: mat-color($background-palette, raised-button);
$bg-focused-button: mat-color($background-palette, focused-button);
$bg-selected-button: mat-color($background-palette, selected-button);
$bg-selected-disabled-button: mat-color($background-palette, selected-disabled-button);
$bg-disabled-button-toggle: mat-color($background-palette, disabled-button-toggle);
$bg-unselected-chip: mat-color($background-palette, unselected-chip);
$bg-disabled-list-option: mat-color($background-palette, disabled-list-option); //<---
//---COMMON_COLORS---------------
//fetch from the theme directly using the is_dark_mode flag
$is-dark-theme: map-get($theme, is-dark); //<---
//primary_text
$fg-dark-primary-text: rgba(black, 0.87);
$fg-light-primary-text: white;
$fg-primary-text-inverse: if($is-dark-theme, $fg-dark-primary-text, $fg-light-primary-text); //<---
//secondary_text
$fg-dark-secondary-text: rgba(black, 0.54);
$fg-light-secondary-text: rgba(white, 0.7);
$fg-secondary-text-inverse: if($is-dark-theme, $fg-dark-secondary-text, $fg-light-secondary-text); //<---
//disabled_text
$fg-dark-disabled-text: rgba(black, 0.38);
$fg-light-disabled-text: rgba(white, 0.5);
$fg-disabled-text-inverse: if($is-dark-theme, $fg-dark-disabled-text, $fg-light-disabled-text); //<---
//dividers
$bg-dark-dividers: rgba(black, 0.12);
$bg-light-dividers: rgba(white, 0.12);
$bg-dividers-inverse: if($is-dark-theme, $bg-dark-dividers, $bg-light-dividers); //<---
//focused
$bg-dark-focused: rgba(black, 0.12);
$bg-light-focused: rgba(white, 0.12);
$bg-focused-inverse: if($is-dark-theme, $bg-light-focused, $bg-light-focused); //<---
//---DERIVED_COLORS--------------
$_bg-ripple: rgba($fg-base, 0.1); //SPEC
$_bg-list-item: $bg-card;
$_scrollbar-bg: rgba($fg_icon, .4);
$_scrollbar-fg: rgba($fg_icon, .05);
$_scrollbar-hover-bg: rgba($fg_icon, .16);
$_scrollbar-hover-fg: rgba($fg_icon, .20); //<----
//###################################################################################
//---STEP-(2/3): CREATE_GLOBAL_CLASSES_THAT_DEPEND_ON_THE_ABOVE_THEME_COLORS--
//###################################################################################
//++++++MAT-LIST-ITEM++++++++++++++++++++++++++++
.mat-list-item {
background-color: $_bg-list-item;
}
.mat-list-item.selected {
background-color: $primary-light;
}
.mat-list-icon {
color: $fg_icon;
} //<---
//###################################################################################
//---STEP-(3/3): PASS_REQUIRED_COLORS_TO_THE_COMPONENTS-----(note: not the $theme)
//###################################################################################
//---Pass_Colors_required_by_the_DashboardComponent
@include dashboard-component-theme( //---
$fg-primary-text, $fg-secondary-text, //---
$fg-primary-text-inverse, $fg-secondary-text-inverse, //---
$_bg-ripple); //<--
//---Pass_Colors_required_by_the_erp-Component
@include erp-component-theme($fg-primary-text, $fg-secondary-text);
//similarly register all your components here and pass only the required colors
} //--------------------------------------------
dashboard.component.scss
@import '~@angular/material/theming';
//colors_passed_by_the register_component.scss
@mixin dashboard-component-theme(
$fg-primary-text, $fg-secondary-text,
$fg-primary-text-inverse, $fg-secondary-text-inverse,
$_bg-ripple) {
//Classes for component's html
.sidenav-header-primary-text {
color: $fg-primary-text-inverse;
font-size: 18px;
line-height: 28px;
margin-bottom: 8px;
}
.sidenav-header-secondary-text {
color: $fg-secondary-text-inverse;
font-size: 15px;
line-height: 15px;
margin-bottom: 2px
}
.list-item-primary-text {
color: $fg-primary-text;
}
.list-item-secondary-text {
color: $fg-secondary-text;
}
}
dashboard.component.ts
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent implements OnInit {
//###-Important: include the ThemeService
constructor(private themeSRVC: ThemeService) {
//...
}
//...
//---
}
dashboard.component.html
<!-- Important set [ngClass] of the root element from the themeSRVC -->
<mat-sidenav-container [ngClass]="themeSRVC.currentThemeNAME">
<!-- .... -->
<!-- Include the classes from the component's scss -->
<h4 class="list-item-primary-text" mat-line>456</h4>
<p class="list-item-scondary-text" mat-line>123</p>
<!-- .... -->
</mat-sidenav-container>
That's It..!
来源:https://stackoverflow.com/questions/53922711/how-to-change-the-global-variable-inside-a-scss-mixin