Skip to content

Dynamic theming with Angular app

Last updated on February 28, 2020

Guys, In this post I’m about to share with you on Implementing dynamic theming to angular application.

Executive and Growth are the two bootstrap themes I’ve used to showcase the demo for ease of understanding.

Why?

Why theming is so important and gains much attention among end-users is to work with our app without straining eye for color contrast and they can even adjust the color based on day time or night time.

Our target would be, how are we going to achieve this one with the angular application. It’s straightforward in vanilla javascript-based application but angular is not. Just we need to tweak the angular compiler configuration file(angular.json) to make this to work. We will see this later part of this post.

Let’s list out what we need to achieve this,

  • Toggle switch (Typically a UI element either a Radio button or Dropdown)
  • Theme files (either 3rd party-oriented theme files or our own theming file)
  • Logic to toggle theme files

We’ve designed our Toggle switch like below,

<div class="ht-tm-element btn-group btn-group-toggle" data-toggle="buttons" (click)="onChangeTheme($event)">
		<label class="btn btn-primary active">
              <input type="radio" name="options" id="option-1" autocomplete="off" value="Executive" checked>Growth</label>
		<label class="btn btn-primary">
              <input type="radio" name="options" id="option-2" autocomplete="off" value="Growth">Executive</label>
</div>

Then we will update to import the required theme files into angular compiler configuration file like below,

"styles": [
              {
                "input": "src/styles/bootstrap-executive.css",
                "lazy": true,
                "bundleName": "executive"
              },
              {
                "input": "src/styles/bootstrap-growth.css",
                "lazy": false,
                "bundleName": "growth"
              },
              "src/styles.scss"
            ],
            "extractCss": true

NOTE

Under the hood, Style files are bundled and injected within the scripts file since our angular compiler uses a webpack. During the run time we will not be able to call the theme file if we are not extracting the injected CSS from scripts.

Thus, we use "extractCss" setting, additionally “lazy” property is used to lazy load the CSS files. After extracted CSS from scripts, each would be named as the name specified in bundleName property.

The final piece would be to write little logic to toggle the theme files when toggling switch UI element.

  onChangeTheme() {
    const selectedExecutive: any  = document.querySelector(
      "input#option-1"
    ).checked;

    const selectedThemeFile =
    selectedExecutive ? "executive.css" : "growth.css";

    const lazyStyleElement: any = document.querySelector(
      `link[rel=stylesheet][href='${selectedThemeFile}']`
    );

    if (typeof lazyStyleElement !== undefined && lazyStyleElement !== null) {
      lazyStyleElement.rel = "stylesheet";
      lazyStyleElement.href =
        selectedExecutive ? "growth.css" : "executive.css";
      this.themeName = selectedExecutive ? 'Growth' : 'Executive';
    }
  }

After all, the resulting would be like below.

Theming1 - Angular app Theming2 - Angular app

You can find the full source code.
That’s it. Always comments are welcome. If any questions please feel free to ping in the comments area let me try to help you out.

References

Published inAngularFrameworks