web-dev-qa-db-fra.com

accéder aux valeurs SASS ($ colors from variables.scss) dans TypeScript (Angular2 ionic2)

Dans Ionic 2, je souhaite accéder au $colors variables du fichier "[mon projet]\src\theme\variables.scss".

Ce fichier contient:

$colors: (
  primary:    #387ef5,
  secondary:  #32db64,
  danger:     #f53d3d,
  light:      #f4f4f4,
  dark:       #222,
  favorite:   #69BB7B
);

Dans un composant, je dessine une toile. Ça ressemble à ça:

import {Component, Input, ViewChild, ElementRef} from '@angular/core';

@Component({
    selector: 'my-graph',
})
@View({
    template: `<canvas #myGraph class='myGraph'
     [attr.width]='_size'
     [attr.height]='_size'></canvas>`,
})

export class MyGraphDiagram {
    private _size: number;

    // get the element with the #myGraph on it
    @ViewChild("myGraph") myGraph: ElementRef; 

    constructor(){
        this._size = 150;
    }

    ngAfterViewInit() { // wait for the view to init before using the element

      let context: CanvasRenderingContext2D = this.myGraph.nativeElement.getContext("2d");
      // HERE THE COLOR IS DEFINED AND I D LIKE TO ACCESS variable.scss TO DO THAT
      context.fillStyle = 'blue';
      context.fillRect(10, 10, 150, 150);
    }

}

Comme on peut le voir, dans ce code, la couleur de la forme est définie: context.fillStyle = 'blue', Je voudrais utiliser à la place quelque chose comme context.fillStyle = '[variables.scss OBJECT].$colors.primary '.

Quelqu'un a une idée?

36
nyluje

Malheureusement, il n’existe aucun moyen d’accéder à la variable SASS directement à partir de code TypeScript/javascript. Cependant, nous pouvons créer une solution de contournement pour accéder à ces variables.

Permettez-moi de décrire brièvement les étapes à suivre pour accéder aux variables SASS à partir du code source TypeScript:

1. Créer un composant d'assistance SASS

Créez ../ providers/sass-helper/sass-helper.component.scss :

$prefix: "--"; //Prefix string for custom CSS properties

//Merges a variable name with $prefix
@function custom-property-name($name) {
    @return $prefix + $name;
}

// Defines a custom property
@mixin define-custom-property($name, $value) {
    #{custom-property-name($name)}: $value;
}

body {
    // Append pre-defined colors in $colors:
    @each $name, $value in $colors {
        @include define-custom-property($name, $value);
    }

    // Append SASS variables which are desired to be accesible:
    @include define-custom-property('background-color', $background-color);
}

Dans ce fichier SCSS, nous créons simplement des propriétés personnalisées à l'intérieur de la section body du DOM. Vous devez ajouter chaque variable SASS que vous voulez rendre accessible dans ce fichier SCSS en utilisant le mixin appelé define-custom-property qui attend deux paramètres: nom de la variable et valeur de la variable.

A titre d'exemple, j'ai ajouté des entrées pour tous les couleurs définies dans $colors ainsi qu’une entrée pour la variable SASS $background-color défini dans mon thème/variables.scss fichier. Vous pouvez ajouter autant de variables que vous le souhaitez.

Créez ../ providers/sass-helper/sass-helper.component.ts :

import { Component } from '@angular/core';

export const PREFIX = '--';

@Component({
    selector: 'sass-helper',
    template: '<div></div>'
})
export class SassHelperComponent {

    constructor() {

    }

    // Read the custom property of body section with given name:
    readProperty(name: string): string {
        let bodyStyles = window.getComputedStyle(document.body);
        return bodyStyles.getPropertyValue(PREFIX + name);
    }
}

2. Intégration du composant SASS Helper

A partir de maintenant, nous pouvons suivre les principes du cadre Ionic2 pour l'intégration et l'utilisation des composants.

  • Ajoutez le nom de la classe du composant (SassHelperComponent) dans la section des déclarations de votre NgModule in app.module.ts
  • Insérez le code HTML suivant dans le modèle HTML de votre page à partir duquel vous souhaitez accéder à ces variables magiques:

    <sass-helper></sass-helper>


3. Utilisation du composant auxiliaire

Dans le fichier TS de votre page, vous devez insérer les lignes suivantes dans votre classe de page:

@ViewChild(SassHelperComponent)
private sassHelper: SassHelperComponent;

Enfin, vous pouvez lire la valeur de toute variable SASS en appelant simplement la méthode de classe enfant comme suit:

// Read $background-color:
this.sassHelper.readProperty('background-color');

// Read primary:
this.sassHelper.readProperty('primary');
36
Mete Cantimur

Une possibilité consiste à générer un fichier .ts À partir du fichier .scss. Un exemple simple de ce processus:

1) Installez npm i --save-dev scss-to-json.

2) Mettez ceci dans votre package.json:

  "scripts": {
    ...
    "scss2json": "echo \"export const SCSS_VARS = \" > src/app/scss-variables.generated.ts && scss-to-json src/variables.scss >> src/app/scss-variables.generated.ts"
  },

et exécutez-le avec npm run scss2json. Les utilisateurs Windows devront ajuster l'exemple.

3) Accéder aux variables:

import {SCSS_VARS} from './scss-variables.generated';
...
console.log(SCSS_VARS['$color-primary-1']);

Un des avantages de ceci est que vous obtiendrez la complétion de caractères de la part de l'IDE et que c'est un moyen assez simple pour atteindre votre objectif en général.

Bien sûr, vous pouvez le rendre plus avancé, par exemple en rendant le fichier généré en lecture seule, en plaçant le script dans son propre fichier .js Et en le faisant fonctionner sur tous les systèmes d'exploitation.

4
bersling

J'aimerais ajouter quelque chose à la réponse @ mete-cantimur.

import {Component, OnInit, ViewEncapsulation} from '@angular/core';

const PREFIX = '--';

@Component({
  selector: 'app-styles-helper',
  templateUrl: './styles-helper.component.html',
  styleUrls: ['./styles-helper.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class StylesHelperComponent implements OnInit {

  ngOnInit(): void {

  }

  readProperty(name: string): string {
    const bodyStyles = window.getComputedStyle(document.body);
    return bodyStyles.getPropertyValue(PREFIX + name);
  }
}

Mon composant d'assistance ne pouvait pas modifier les styles de corps. Même si j'ai tout configuré correctement, les propriétés personnalisées n'étaient pas enregistrées.

Je devais ajouter encapsulation: ViewEncapsulation.None au composant afin de lui permettre de modifier les styles de corps.

J'espère que cela t'aides.

3
yuva