Aller au contenu principal

Thèmes et styles

Les styles d'une application Lagoon ne sont pas écrits en CSS : ils sont générés à chaque build à partir des sources SCSS des modules Lagoon.UI* et des fichiers SCSS du projet client. Cette page explique comment le résultat est composé, comment le personnaliser et comment proposer plusieurs thèmes à l'utilisateur.

Fichiers de styles de l'application​

Les sources SCSS de l'application se trouvent dans Client/resources/styles/. Pour une application à thème unique, le point d'entrée est main.scss :

Client/resources/styles/main.scss
// Use RGAA compatible style
$custom-rgaa: false;
// Label position
$custom-label-outside: false;
// Set the header logo
$header-logo: "~/images/header-logo.png";

// Spinner
$spinner: 'logo';
$sp-color: $primary;

Le build compile ce fichier en Client/wwwroot/_vroot/styles.css. Le dossier _vroot est une sortie de build : ne le modifiez pas et ne le versionnez pas. Pour changer le rendu, modifiez toujours les sources SCSS.

Aucun outil externe

La compilation est faite par les tâches MSBuild du package Lagoon.Build, avant chaque build de l'application. En Release, la feuille de style est minifiée ; en Debug, elle reste lisible. La propriété <LagoonMinifyCss>true|false</LagoonMinifyCss> du projet force l'un ou l'autre.

Ordre d'agrégation​

Toutes les sources sont fusionnées en un seul document SCSS, dans cet ordre :

  1. Lagoon.UI : Bootstrap, variables et styles des composants ;
  2. les autres modules Lagoon.UI* référencés (Lagoon.UI.GridView, Lagoon.UI.Notifications…) ;
  3. le fichier de l'application (main.scss, ou chaque theme-*.scss).

Redéfinir une variable​

Le moteur SCSS de Lagoon a été modifié pour autoriser la redéfinition des variables au niveau global : la dernière affectation d'une variable s'applique à tout le document, y compris aux styles des modules déclarés avant elle. Le mot-clé !default est donc inutile.

Concrètement, toutes les déclarations de variables sont regroupées avant les règles de style, en ne gardant que la dernière valeur de chacune et en les réordonnant selon leurs dépendances. Une variable affectée dans le fichier de l'application, qui passe en dernier, l'emporte sur les valeurs définies par les modules :

Client/resources/styles/main.scss
// Every Lagoon.UI rule using $primary picks up this value
$primary: #0B5394;
// A variable can reference another one, whatever the declaration order
$sp-color: $primary;

Dans les fichiers de l'application, le préfixe ~/ désigne la racine du site (~/images/logo.png). Dans les sources d'un module, il désigne le dossier _content/<Module>/ de ce module.

Options $custom-*​

Certaines variables booléennes sélectionnent tout un jeu de variables et de styles :

VariableEffetValeur par défaut
$custom-rgaaPalette plus contrastée et ajustements pour l'accessibilité (RGAA).false
$custom-label-outsideLibellés affichés au-dessus des champs, au lieu d'être placés dans le champ comme un placeholder.false

Voir Accessibilité pour l'usage de ces options.

Proposer plusieurs thèmes​

Une application peut proposer plusieurs thèmes, au choix de l'utilisateur. Un thème est une feuille de style complète, compilée à partir d'un fichier theme-<nom>.scss. Les thèmes s'appuient sur les mêmes modules et font varier leurs variables (couleurs, options $custom-*, logos, spinner…).

Déclarer les thèmes​

Créez un fichier theme-<nom>.scss par thème dans Client/resources/styles/, et placez ce qui est commun dans un fichier partagé importé par chacun d'eux :

Client/resources/styles/theme-standard.scss
// Label position
$custom-label-outside: false;
// Use RGAA compatible style
$custom-rgaa: false;

@import "shared";
Client/resources/styles/theme-rgaa.scss
// Use RGAA compatible style
$custom-rgaa: true;
// Label position
$custom-label-outside: true;

@import "shared";
Client/resources/styles/shared.scss
// Set the header logo
$header-logo: "~/images/header-logo.png";

.my-custom-class {
color: $primary;
}

Chaque theme-<nom>.scss est compilé en _vroot/theme-<nom>.css, et le nom du thème est la partie <nom> du fichier (standard et rgaa dans l'exemple).

attention
main.scss est ignoré

Dès qu'un fichier theme-*.scss existe, main.scss n'est plus compilé et styles.css n'est plus produit. Déplacez son contenu dans le fichier partagé.

Au démarrage, le serveur détecte les thèmes à partir des fichiers theme-*.css générés, et les transmet au client. Aucune liste n'est à maintenir.

Choisir le thème par défaut​

Le thème appliqué tant que l'utilisateur n'en a pas choisi un autre se règle avec la clé App:Theme de l'appsettings.json du serveur :

Server/appsettings.json
{
"App": {
"Theme": "rgaa"
}
}

Si la clé est absente, ou si elle ne correspond à aucun thème, le premier thème par ordre alphabétique est utilisé.

attention

Ne renseignez App:Theme que si l'application déclare des thèmes : sans fichier theme-*.scss, la page d'accueil chercherait une feuille theme-<nom>.css qui n'existe pas.

Laisser l'utilisateur choisir​

Ajoutez LgThemeMenuItem au menu. Il ouvre, dans une petite fenêtre modale, la page de sélection du thème, qui affiche un bouton par thème :

MenuConfiguration.razor
<LgThemeMenuItem />

Le libellé de chaque bouton est la clé de traduction theme-<nom>. Déclarez-la dans le Dico.xml du projet client :

Client/Dico.xml
<string key="theme-standard" fr="Standard" en="Standard" />
<string key="theme-rgaa" fr="RGAA" en="WCAG" />

Le choix est appliqué immédiatement, sans recharger la page, et mémorisé dans le navigateur (clé theme du localStorage). Il est donc propre à chaque navigateur, et non au compte de l'utilisateur. Si le thème mémorisé ne peut pas être chargé, par exemple parce qu'il a été supprimé, l'application revient au thème par défaut.

Changer de thème par code​

L'application cliente (App, disponible dans tout composant héritant de LgComponentBase) expose les thèmes :

MembreRôle
App.ThemesListe des thèmes disponibles (vide pour une application à thème unique).
App.GetCurrentTheme()Nom du thème affiché.
App.SetTheme(string theme)Applique et mémorise un thème ; lève une ArgumentException si le nom n'est pas dans App.Themes.

Favicon et icône par thème​

Chaque thème peut avoir sa propre icône d'onglet et sa propre icône d'application : déposez favicon-<nom>.ico et icon-<nom>.png dans Client/wwwroot/, à côté de favicon.ico et icon.png. Elles sont échangées au changement de thème. Un thème sans fichier dédié utilise favicon.ico et icon.png.

Page d'accueil (index.html)​

Gardez le lien vers styles.css dans le index.html du client, même dans une application multi-thème :

Client/wwwroot/index.html
<link rel="stylesheet" href="styles.css?v={APP_VERSION}" />

Le serveur le réécrit à la volée pour charger la feuille du thème mémorisé ou du thème par défaut, et ajoute un script de préchargement de cette feuille en tête de page. L'empreinte de ce script est ajoutée automatiquement à la politique de sécurité du contenu (CSP).

Voir aussi​