Skip to content

Implement a Theme Switcher for a Blazor application.

License

Notifications You must be signed in to change notification settings

DevExpress-Examples/blazor-theme-and-size-mode-switcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

177 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Switch Themes and Size Modes within Blazor Apps at Runtime

This example adds a theme switcher to a DevExpress-powered Blazor app. Users can switch between DevExpress Fluent and Classic themes, and external Bootstrap themes. This example uses the DxResourceManager.RegisterTheme(ITheme) method to apply a theme at application startup and the IThemeChangeService.SetTheme() method to change the theme at runtime.

This example also implements a size mode combobox designed to switch between small, medium, and large size modes.

Blazor - Theme and Size Mode Switchers

Add Resources and Services

To switch themes and size modes at runtime, configure your Blazor application as follows:

  1. Copy the example switcher-resources folder to your application wwwroot folder. The switcher-resources folder has the following structure:

    • js/cookies-manager.js
      Contains a function that stores the theme in a cookie variable.
    • js/size-manager.js
      Contains a function that assigns selected size mode to the --global-size CSS variable.
    • theme-switcher.css
      Contains CSS rules that define theme switcher appearance and behavior.
  2. Add the following services to your application (copy corresponding files from the Services folder):

  3. In the _Imports.razor file, register {ProjectName}.Components.ThemeSwitcher and {ProjectName}.Services namespaces:

    @using {ProjectName}.Components.ThemeSwitcher
    @using {ProjectName}.Services
  4. Register services in the Program.cs file:

    builder.Services.AddDevExpressBlazor();
    builder.Services.AddMvc();
    builder.Services.AddHttpContextAccessor();
    builder.Services.AddScoped<ThemesService>();
    builder.Services.AddTransient<CookiesService>();
    builder.Services.AddScoped<SizeManager>();

Configure Available Themes

The theme switcher includes the following themes:

  • DevExpress Fluent (Light/Dark with custom accent color support)
  • DevExpress Classic (Blazing Berry, Blazing Dark, Purple, and Office White)
  • Bootstrap External

Create a Themes.cs file and configure themes:

  1. For Classic themes, choose a theme from the built-in DevExpress Blazor Themes collection and add custom stylesheets (using the Clone() method):

    public static readonly ITheme BlazingBerry = Themes.BlazingBerry.Clone(props => {
        props.AddFilePaths("css/theme-bs.css");
    });
    public static readonly ITheme BlazingDark = Themes.BlazingDark.Clone(props => {
        props.AddFilePaths("css/theme-bs.css");
    });
    public static readonly ITheme Purple = Themes.Purple.Clone(props => {
        props.AddFilePaths("css/theme-bs.css");
    });
    public static readonly ITheme OfficeWhite = Themes.OfficeWhite.Clone(props => {
        props.AddFilePaths("css/theme-bs.css");
    });
  2. For Fluent themes, call the Clone() method to add theme stylesheets and change theme mode:

    public static ITheme FluentLight(string? accent = null) { 
        return Themes.Fluent.Clone(props => {
            props.Name = "FluentLight" + accent?.PadLeft(8);
            props.SetCustomAccentColor(accent);
            props.AddFilePaths("css/theme-fluent.css");
        });
    }
    public static ITheme FluentDark(string? accent = null) {
        return Themes.Fluent.Clone(props => {
            props.Name = "FluentDark" + accent?.PadLeft(8);
            props.SetCustomAccentColor(accent);
            props.Mode = ThemeMode.Dark;
            props.AddFilePaths("css/theme-fluent.css");
        });
    }
  3. For Bootstrap themes, call the Clone() method to add a Bootstrap theme stylesheet. Use the same approach if you wish to apply your own stylesheets.

    public static readonly ITheme BootstrapDefault = Themes.BootstrapExternal.Clone(props => {
        props.Name = "Bootstrap";
        props.AddFilePaths("https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css");
        props.AddFilePaths("css/theme-bs.css");
    });
  4. Create a list of themes:

    public enum MyTheme {
        FluentLight,
        FluentDark,
    
        BlazingBerry,
        BlazingDark,
        Purple,
        OfficeWhite,
    
        Bootstrap
    }

Use Custom Accent Colors in Fluent Themes

The theme switcher allows you to apply a Fluent theme with a custom accent color as follows:

  • A masked input field used to enter hex color values
  • A color picker for visual color selection

The theme is applied automatically when a user selects a color.

Review implementation details in the ThemeSwitcherContainer.razor file.

Add Custom Stylesheets to the Application (Apply Styles to Non-DevExpress UI Elements)

DevExpress Blazor themes affect DevExpress components only. To apply theme-specific styles to non-DevExpress elements or the entire application, add external stylesheets to the theme using its AddFilePaths() method:

public static readonly ITheme BootstrapDefault = Themes.BootstrapExternal.Clone(props => {
    props.Name = "Bootstrap";
    // Links a Bootstrap theme stylesheet
    props.AddFilePaths("https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css");
    // Links a custom stylesheet
    props.AddFilePaths("css/theme-bs.css");
});

Bootstrap themes require external theme-specific stylesheets. Once you register a Bootstrap theme, call the Clone() method and add the stylesheet using theme properties.

Change Bootstrap Theme Color Modes

If you wish to use dark Bootstrap themes, apply a data-bs-theme attribute to the root <html> element:

  • data-bs-theme="light" for light themes
  • data-bs-theme="dark" for dark themes

Refer to the following article for additional information: Color Modes.

Add a Theme Switcher to Your Application

Replicate the steps below to add a theme switcher to your application:

  1. Copy the ThemeSwitcher folder to your project. The folder contains:

  2. Add the following code to the Components/App.razor file:

    • Inject services with the [Inject] attribute:

      @using Microsoft.AspNetCore.Mvc.ViewFeatures
      @using DevExpress.Blazor
      @inject IHttpContextAccessor HttpContextAccessor
      @inject IFileVersionProvider FileVersionProvider
      @inject ThemesService ThemesService
    • Add script and stylesheet links to the file's <head> section and call the DxResourceManager.RegisterTheme(ITheme) method to apply a theme on application startup:

      <head>
          @* ... *@
          <script src=@AppendVersion("switcher-resources/js/cookies-manager.js")></script>
          <link href=@AppendVersion("switcher-resources/theme-switcher.css") rel="stylesheet" />
      
          @DxResourceManager.RegisterTheme(Theme)
          @DxResourceManager.RegisterScripts()
      
          <link href=@AppendVersion("css/site.css") rel="stylesheet" />
          <HeadOutlet @rendermode="InteractiveServer" />
      </head>
    • Obtain the theme from cookies during component initialization:

      @code {
          private ITheme Theme;
          private string AppendVersion(string path) => FileVersionProvider.AddFileVersionToPath("/", path);
      
          protected override void OnInitialized() {
              Theme = ThemesService.GetThemeFromCookies(HttpContextAccessor);
          }
      }
  3. Declare the theme switcher component in the MainLayout.razor file:

    <div class="nav-buttons-container">
        @* Navigation buttons *@
        <div class="switcher-panel">
            <ThemeSwitcher />
        </div>
    </div>

Add a Size Mode Switcher

To change size modes at runtime, you must:

  1. Copy the SizeChanger.razor file to the Components/Layout folder. This file creates a size mode menu and injects the SizeManager service.

  2. Reference the size-manager.js script in the <head> section of the App.razor file:

    <head>
        @* ... *@
        <script src=@AppendVersion("switcher-resources/js/size-manager.js")></script>
        @* ... *@
    </head>
  3. Use the --global-size CSS variable to define font size application-wide:

    html, body {
        /* ... */
        font-size: var(--global-size);
    }
  4. Declare the size mode switcher component in the MainLayout.razor file:

    <div class="nav-buttons-container">
        @* Navigation buttons *@
        <div class="switcher-panel">
            <SizeChanger />
            <ThemeSwitcher />
        </div>
    </div>

Files to Review

Documentation

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

About

Implement a Theme Switcher for a Blazor application.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 17