24047

how to change the global variable inside a scss mixin

Question:

<blockquote>

theme-variables.scss

</blockquote> //--------------------------------------------------------- //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 } <blockquote>

component.scss

</blockquote> @import "../../../../assets/themes/theme-variables.scss"; .text-color { color: $fg-primary-text; //use the variable (but it is still red) }

<strong>But the color is still red</strong> 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

Answer1:

You will need a mixin function in your component.scss.

And then have a @include in your main.scss file.

<strong>component.scss</strong>

@mixin text-color-mixin($theme) { $is-dark-theme: map-get($theme, is-dark); .text-color { color: if($is-dark-theme, red, blue); } }

<strong>main.scss</strong>

@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 <a href="https://github.com/angular/material.angular.io" rel="nofollow">https://github.com/angular/material.angular.io</a>

This is the official repo for the angular material io documentation site.

<strong>EDIT</strong>

I think this also answers your question

<a href="https://stackoverflow.com/questions/40480320/how-to-manipulate-scss-variables-in-angular2-components?rq=1" rel="nofollow">How to manipulate scss variables in Angular2 components</a>

Answer2:

<blockquote>

Atlast I've found a solution, and I'm sharing here for those who need it.

<strong>Note:</strong> I know it's very long.. but read patiently you may get something <strong>or correct me If I'm doing anything wrong.</strong>

</blockquote>

First start from the theme.service

<blockquote>

<strong>theme.service.ts</strong>

</blockquote>

<pre class="snippet-code-js lang-js prettyprint-override">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; } } } <blockquote>

<strong>app.module.ts</strong>

</blockquote>

<pre class="snippet-code-js lang-js prettyprint-override">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 } }

<strong>Lets Assume I've 2 themes</strong>:

<blockquote>

<strong>1) light-theme.scss</strong>

</blockquote>

<pre class="snippet-code-css lang-css prettyprint-override">// 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); <blockquote>

<strong>2) dark-theme.scss</strong>

</blockquote>

<pre class="snippet-code-css lang-css prettyprint-override">// 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); <blockquote>

<strong>styles.scss</strong>

</blockquote>

<pre class="snippet-code-css lang-css prettyprint-override">/* 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 <blockquote>

<strong>register_components.scss</strong>

</blockquote>

<pre class="snippet-code-css lang-css prettyprint-override">@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 } //-------------------------------------------- <blockquote>

<strong>dashboard.component.scss</strong>

</blockquote>

<pre class="snippet-code-css lang-css prettyprint-override">@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; } } <blockquote>

<strong>dashboard.component.ts</strong>

</blockquote>

<pre class="snippet-code-js lang-js prettyprint-override">@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) { //... } //... //--- } <blockquote>

<strong>dashboard.component.html</strong>

</blockquote>

<pre class="snippet-code-html lang-html prettyprint-override"><!-- 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

<!-- .... --> </mat-sidenav-container>
<blockquote>

That's It..!

</blockquote>

Recommend