Davrozz
Davrozz

Reputation: 47

.NET MAUI Blazor light/dark theme, load specific stylesheets via headcontent

I am creating a .net MAUI Blazor Hybrid app. In this, I want to create a dark and light theme using css stylesheets (no MudBlazor).

What I am trying now, is using a lightMode.css and darkMode.css that contain the correct colors for that theme. When dark mode is on, the MainLayout, and thus all pages, should use the darkMode.css

Example in MainLayout.razor:


<HeadContent>
    @if (isDark)
    {
        <link href="css/darkMode.css" rel="stylesheet"/>
    }
    else
    {
        <link href="css/lightMode.css" rel="stylesheet"/>
    }   
</HeadContent>

// HTML and c# here

However, this is not working. Looking at the page, none of this headcontent is in the tag of the page, and adding them directly to the index.html page only results in the last of the files being applied.

I have looked at other solutions here, but they never mention how they achieved this with css, like in this post: Light and dark theme for my Maui Blazor app

Any suggestions as to how I can achieve a dark/light theme implementation with css? Other ideas are welcome too, but this looks like the most simple one to me.

Thanks in advance.

Upvotes: 1

Views: 1343

Answers (1)

Davrozz
Davrozz

Reputation: 47

I wound up doing doing it slightly differently, as I couldn't get HeadContent to work (probably since I removed the bootstrap parts as I wanted to do my own styling fully).

I ended up following a modified version of this answer: https://stackoverflow.com/a/63563797/17389553 by @benjamin. I do not add or remove classes to the HTML elements.

However, by using the such direct html/js element manipulators I simply get the <head> element, then the stylesheet <link> that contains the theme css file, and switch it out with light/dark depending on the toggle.

I will describe it a bit more in depth here.

My code: In my MainLayour.razor class, I added this simple line which takes care of it:

<ElementManipulator IsDarkTheme="_isDark"></ElementManipulator>

Where _isDark is supplied by a simple toggle button.

This class is defined in ElementManipulator.razor:

@inject IJSRuntime JSRuntime

@code {

    protected override async Task OnParametersSetAsync()
    {
        if (IsDarkTheme is not null)
            await JSRuntime.InvokeVoidAsync("toggleThemeStyleSheet", IsDarkTheme);
    }

    [Parameter]
    public bool? IsDarkTheme { get; set; }
}

Which invokes the toggleThemeStyleSheet function in the javascript file ElementManipulator.js:

var getHeadElement = function () {
    return document.getElementsByTagName("head")[0];
};

var toggleThemeStyleSheet = function (isDarkTheme) {
    let themeLink = getHeadElement().getElementsByClassName("theme")[0];
    let theme = isDarkTheme ? "darkTheme.css" : "lightTheme.css";
    themeLink.href = "_content/MyProject.UI/css/" + theme;
};

Which then swaps out the lightTheme.css with darkTheme.css and vice versa.

Upvotes: 0

Related Questions