Themeservice system settings

Hi @Fady1956,

This can't be easily done as a built-in because dark and light themes are defined in separate files. We would have to put everything in one file in order for it work just with a CSS selector.

Having said that there are two options to implement what you are after:

Use a helper CSS file or style

This CSS would @import the required CSS file depending on the CSS media query. It would be included instead of using RadzenTheme and the `ThemeService.

To implement this solution replace <RadzenTheme /> in your App.razor with this:

<style>
 @@import url(@($"_content/Radzen.Blazor/css/material-base.css?v={typeof(Radzen.Colors).Assembly.GetName().Version}")) (prefers-color-scheme: light);
 @@import url(@($"_content/Radzen.Blazor/css/material-dark-base.css?v={typeof(Radzen.Colors).Assembly.GetName().Version}")) (prefers-color-scheme: dark);
</style>

This code snippet will import the required CSS file depending on the user system settings. Using @@ is required because Blazor treats @ as a special symbol which needs to be escaped. This ?v={typeof(Radzen.Colors).Assembly.GetName().Version} implements cache busting and prevents the browser from loading a stale theme file after upgrading Radzen.Blazor.

Pros
  • Easier to implement.
Cons
  • It overrides RadzenTheme and ThemeService which means RadzenAppearanceToggle won't work.

Use a "landing" page

This approach involves having a landing page (with route "/") which runs the CSS query with JavaScript interop and if dark mode is requested sets the current theme and then redirects to the app.

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        // Use JS interop to run the CSS media query
        var darkMode = await JSRuntime.InvokeAsync<bool>("eval", "window.matchMedia('(prefers-color-scheme: dark)').matches");

        if (darkMode)
        {
            // Set the current theme if needed
            ThemeService.SetTheme("material-dark");
        }

        // Redirect to the real start page of the application
        NavigationManager.NavigateTo("/index");
    }
}
Pros
  • Still relies on ThemeService which means RadzenApperanceToggle would work as expected as well as everything else that could required `ThemeService.
Cons
  • Requires a new page and a new empty layout.

I am attaching two apps that implement both approaches.

SystemThemeApp.zip (263.2 KB)
SystemThemeCss.zip (258.7 KB)

2 Likes