angularangular9ng-zorro-antd

How to change the ng-zorro theme at runtime


I did a lot of research, and couldn't find a way to generate the ng-zorro themes and change it on the runtime.

Finally, I could find a way to do this.


Solution

  • Demo: https://ashotaleqs.github.io/ng-zorro-switch-theme/

    1. At first you need to install less-plugin-clean-css dev dependency by command npm i less -D less-plugin-clean-css -D

    2. Create themes folder in assets folder

    3. Define less-compiler.js which contains:

    const less = require('less');
    const LessPluginCleanCSS = require('less-plugin-clean-css');
    const fs = require('fs');
    
    // ng zorro defined styles
    const basicStyles = `@import './node_modules/ng-zorro-antd/ng-zorro-antd.less';`;
    // ng zorro compact theme variables
    const compactThemeVars = require('ng-zorro-antd/compact-theme');
    // ng zorro dark theme variables
    const darkThemeVars = require('ng-zorro-antd/dark-theme');
    
    less.render(`${basicStyles}`, {
      javascriptEnabled: true,
      plugins: [new LessPluginCleanCSS({ advanced: true })],
      modifyVars: {
    
        ...compactThemeVars,
        ...{
          // for the compact theme
          // you need to add your color variables here
          // you can find the full variables list here
          // https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/scripts/site/_site/doc/theme.less
          'primary-color': '#111521',
          'error-color': 'green'
        }
      }
    }).then(data => {
      fs.writeFileSync(
        // output path for the theme style
        './src/assets/themes/compact.css',
        data.css
      )
    }).catch(e => {
      // log the render error
      console.error(e);
    });
    
    less.render(`${basicStyles}`, {
      javascriptEnabled: true,
      plugins: [new LessPluginCleanCSS({ advanced: true })],
      modifyVars: {
        ...darkThemeVars,
        ...{
          // for the dark theme
          // you need to add your color variables here
          // you can find the full variables list here
          // https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/scripts/site/_site/doc/theme.less
          'primary-color': '#02cadb',
          'error-color': 'yellow'
        }
      }
    }).then(data => {
      fs.writeFileSync(
        // output path for the theme style
        './src/assets/themes/dark.css',
        data.css
      )
    }).catch(e => {
      // log the render error
      console.error(e);
    });
    

    here is the link of the full variables less variables

    1. Run node ./less-compiler.js in the terminal (this command should generate the dark.css and compact.css files in the src/assets/themes folder)

    2. (optional) If you want to run node ./less-compiler.js every time when you build the project, you can replace "build": "ng build", with "build": "ng build && node ./less-compiler.js", in package.json and after you can build your project by npm run build command.

    3. add <link rel="stylesheet" id="theme-link" href="/assets/themes/compact.css"> into the head of your index.html file.

    4. Define a function that helps you remove or add the link of the theme into the head. (In my case the function defined in the app.component.ts file)

    // ..........................
    export class AppComponent {
      theme = '';
      constructor() {
          setInterval(() => {
             this.changeTheme()
          }, 2000);
      }
    
      changeTheme() {
        this.theme = this.theme === 'dark' ? '' : 'dark';
        const style = document.getElementById('theme-link') as HTMLLinkElement;
        if (this.theme === 'dark') {
          style.href = '/assets/themes/dark.css';
        } else {
          style.href = '/assets/themes/compact.css';
        }
      }
    }
    

    I hope this can help you easily organize the runtime theme switching.

    and also here is the link of the simple project repository

    GitHub Repository