Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access SCSS/SASS variables in Angular Components

I have to find a way to access SCSS variables (and its values) within the HTML of my Angular5 components and I hope someone can help me with this.

In my variables.scss I've some variables, for example:

...
$primary-1: #cccccc;
$primary-2: #666666;
$primary-3: #000000;
...

Let's say my color palette consists of these colors.

I also created some Angular components, for reusing tables, charts et cetera.
These components make use of ng2-charts/Chart.js. One of them is the LineChartComponent, which I would use to clarify my problem.

...
<app-line-chart 
    height="500" 
    [hexColors]="['#ccccccc', '#666666','#000000']" 
    [datasetLabels]="..." 
    [datasets]="..."
    [axisLabels]="..."></app-line-chart>
...

As you can see I can set some hexColors. These will be translated to RGBA colors within the LineChartComponent.

But now... Let's say my palette of colors is changing.
I then have to change my colors within the variables.scss but also in all places where these colors are passed through the different components.

Until now I haven't found a way to access the variables within my components. I thought about creating a global typescript file where these colors are also defined, so I only have to edit two places and I get something like this:

variables.scss

...
$primary-1: #cccccc;
$primary-2: #666666;
$primary-3: #000000;
...

color-variables.ts

export const COLORS = Object.freeze({ 
    primary1: '#cccccc',
    primary2: '#666666',
    primary3: '#000000'
});

Then set the global variable within the components where I do need colors.

example.component.ts

import {COLORS} from '../globals/variables';
...
@Component({...})
export class SomeComponent {
    ...
    colors = COLORS;
    ...
}

And then set the hexColors of my components to this:

...
<app-line-chart 
    height="500" 
    [hexColors]="[colors.primary1, colors.primary2, colors.primary3]" 
    [datasetLabels]="..." 
    [datasets]="..." 
    [axisLabels]="..."></app-line-chart>
...

But then again I have to modify two places when my color palette has changed.
This doesn't sound logical to me and I am convinced that there should be a better way of doing this, so I only have to edit one place when I want to replace a color.
Preferably by editing the SCSS, because the stylesheet is (in my opinion) responsible for style and coloring. Is there anyone who can share his/her thoughts?

Edit: amit77309 mentioned that this may be a duplicate of access SASS values ($colors from variables.scss) in Typescript (Angular2 ionic2) , but that solution does not seem to work.
I am not using ionic, but looking at the solution that might not be the problem. The custom properties are not listed within the property list of bodyStyles, so they cannot be accessed.

like image 302
Stephan Schrijver Avatar asked Apr 18 '18 14:04

Stephan Schrijver


1 Answers

You can't directly access SASS variables from typescript or html, but with css custom properties it's easy to do.

// get variable from inline style
element.style.getPropertyValue("--my-var");

// get variable from wherever
getComputedStyle(element).getPropertyValue("--my-var");

// set variable on inline style
element.style.setProperty("--my-var", jsVar + 4);

keep in mind that in angular element would refer to a nativeElement.

The post @amit77309 linked shows one of the ways you can make it easier to declare custom properties along with the sass variables, but if you find it too complex, you could simply declare them together. As long as you have the variables set as custom properties, you can access them in your typescript and make them available in the template as well.

It's arguable that this is indeed a duplicate, as that answer does solve your question, but this is a simplified and more basic approach, seem as you expressed it was too complicated and you couldn't get it to work. Perhaps you can achieve you goal by understanding the underlying mechanism behind it a little more.

like image 196
Henrique Erzinger Avatar answered Nov 15 '22 04:11

Henrique Erzinger