Basculer les thèmes avec Javascript Interop dans Blazor

· 4 min de lecture

Pour les personnes comme moi qui souffrent de flashbacks à chaque fois que j’ouvre une page Web, j’ai trouvé une solution très simple pour basculer entre les modes clair et sombre à l’aide de Javascript et l’appeler depuis Blazor à l’aide de Javascript Interop.

Définition de l’attribut parent

Tout d’abord, nous devons identifier l’élément parent avec un identifiant, car nous changeons les couleurs en fonction de la valeur de cet identifiant.

Pour faire cela en Javascript, nous devrons exécuter cette commande

document.documentElement.setAttribute('data-theme', 'YOUR_IDFENTIFIER');

Dans notre cas, nous souhaitons avoir deux identifiants pour chaque type de style, qui sont light et dark.

Création d’un fichier Javascript pour gérer la logique

Nous avons maintenant la fonction pour mettre à jour l’identifiant, créons maintenant un fichier Javscript avec une fonction qui exécute cette logique. Notre fichier va s’appeler app.js

Dans ce fichier, nous aurons une fonction qui appellera le code que nous avons mentionné plus tôt.

var toggleTheme = function (identifier) {
    document.documentElement.setAttribute('data-theme', identifier);
}

Ajout d’un fichier Javascript à Blazor

Ajoutez le script à l’application Blazor en l’ajoutant à l’endroit où se trouvent les scripts.

<script src="~/js/app.js"></script>

Création du service

Maintenant que nous avons le code Javascript, nous devons créer un service qui s’appellera ThemeToggleService.

Ce service gérera la logique pour basculer entre le thème light et dark.

Injection de JSInterop

Pour appeler n’importe quel Javascipt, nous devons appeler JSInterop, nous devons donc créer une propriété qui injectera.

using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace BlazorDarkmodeToggle.Data
{
    private readonly IJSRuntime jSRuntime;

    public ThemeToggleService(IJSRuntime jSRuntime)
    {
        this.jSRuntime = jSRuntime;
    }
}

Fonction pour définir l’identifiant

Maintenant que le service est créé, créons la fonction pour définir l’identifiant, cette fonction mettra simplement à jour le data-theme dans la page.

using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace BlazorDarkmodeToggle.Data
{
    public class ThemeToggleService
    {
        private readonly IJSRuntime jSRuntime;

        public ThemeToggleService(IJSRuntime jSRuntime)
        {
            this.jSRuntime = jSRuntime;
        }

        public bool IsLightTheme { get; set; } = true;
        public string GetIdentifier => IsLightTheme ? "light" : "dark";

        public async Task ToggleTheme() {
            IsLightTheme = !IsLightTheme;
            await jSRuntime.InvokeVoidAsync("toggleTheme", GetIdentifier);
        }
    }
}

Ajouter un service au démarrage

Afin de rendre le service disponible pour tous les composants et pages, nous devons l’ajouter au fichier Program.cs.

builder.Services.AddSingleton<ThemeToggleService>();

Donc le fichier finira comme ça

using BlazorDarkmodeToggle.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddSingleton<ThemeToggleService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

Gardez à l’esprit que cela peut changer selon que vous utilisez Blazor Server ou Blazor WebAssembly.

Préparer le CSS

Maintenant que nous avons une partie du code prête, nous devons commencer à travailler sur le CSS. Ce que nous devons faire est de définir toutes les propriétés CSS qui gèrent les couleurs CSS, l’arrière-plan, etc. sur une variable.

:root {
    --background-color:#ffffff;
    --text-color:#000000;
}

Une fois que nous avons fait cela, en utilisant l’identifiant, nous pouvons facilement changer d’identifiant, et il utilisera l’une ou l’autre valeur.

[data-theme="dark"] {
    --background-color: #000000;
    --text-color: #ffffff;
}

Pour le fondu d’animation sympa, nous ajouterons simplement une propriété transition à tous, pour que ça ait l’air bien.

* {
    transition: all 250ms;
}

Nous allons maintenant attribuer ces variables à certaines classes CSS, afin que nous puissions les voir sur la page Blazor.

.app-background {
    background-color: var(--background-color);
    width: 200px;
    height: 200px;
}

.app-text {
    color: var(--text-color);
}

Pensez à ajouter le fichier à l’application Blazor en l’ajoutant sur le head.

<link href="css/app.css" rel="stylesheet" />

Appel depuis Blazor

Alors comment allons-nous tester cela ? Pour faire simple, nous allons simplement ajouter un div avec la classe app-background, et à l’intérieur il y aura un p avec la classe app-text .Créons donc une page appelée Theme.razor sous le dossier Pages et ajoutons du code pour cela.

@page "/theme"
@using BlazorDarkmodeToggle.Data
@inject ThemeToggleService ThemeToggleService

<button class="btn btn-primary" @onclick=Toggle>Toggle theme</button>

<br />

<div class="app-background">
    <p class="app-text">Hello world!</p>
</div>

@code{
    public async Task Toggle()
    {
        await this.ThemeToggleService.ToggleTheme();
    }
}

Nous pourrions tester cela en allant sur /theme, mais ajoutons-le également à la barre de navigation

<div class="nav-item px-3">
    <NavLink class="nav-link" href="theme">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Theme togle
    </NavLink>
</div>

Tests

Comme vous pouvez le voir, dès que nous changeons de thème, d’arrière-plan et de couleur de police, vous pouvez maintenant voir à quel point cela est puissant. Si vous développez réellement la page entière en utilisant ces variables sur CSS, vous pouvez avoir différents thèmes et simplement les basculer !

Comme c’est génial !!

#Code

L’intégralité de ce projet est sur Github et vous pouvez le trouver ici !

Si vous avez des problèmes ou des questions, n’hésitez pas à me contacter sur n’importe quel réseau social à @emimontesdeoca (sur Twitter, c’est en fait @emimontesdeocaa avec deux aa à la fin). Vous pouvez également retrouver la plupart de mes réseaux sociaux sur l’en-tête du blog.

J’espère que vous avez aimé le message !

Ressources