3

I've got an application where I have to configure and use less for dynamic theme implementation. The issue is we are not using angular-cli and configuration is bit weird here, so we are manually bootstrapping angular modules.

Following is the configuration of app:

package.json

      "dependencies": {
        "@angular/common": "^4.0.0",
        "@angular/compiler": "^4.0.0",
        "@angular/core": "^4.0.0",
        "@angular/forms": "^4.0.0",
        "@angular/http": "^4.0.0",
        "@angular/platform-browser": "^4.0.0",
        "@angular/platform-browser-dynamic": "^4.0.0",
        "@angular/router": "^4.0.0",
        "@angular/upgrade": "^4.0.0",
        "@angular/animations": "^4.0.1",
        "bootstrap": "^3.3.7",
        "core-js": "^2.4.1",
        "reflect-metadata": "^0.1.8",
        "rxjs": "^5.0.1",
        "systemjs": "0.19.39",
        "zone.js": "^0.8.4"
      },
and so on..

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import { ThemeModule } from "./theme.module";

window.appnamespace.platform = platformBrowserDynamic();
window.appnamespace.AppModule = AppModule
window.appnamespace.ThemeModule = ThemeModule;

theme.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { ThemeComponent } from "./theme.component";
import { ThemeToolbar } from "./Themes/theme-toolbar/theme-toolbar.component";
import { ThemePreview } from "./Themes/theme-preview/theme-preview.component";
import { ThemeService } from "./services/themeManagement.service";

const PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
  suppressScrollX: true
};

@NgModule({
  imports: [
    BrowserModule,
  ],
  declarations: [
    ThemeComponent,
    ThemeToolbar,
    ThemePreview,
    SetFocusDirective
  ],
  providers: [ThemeService, LocalizeThemeService, CommonService],
  bootstrap: [ThemeComponent]
})

export class ThemeModule { }

its component:

@Component({
  selector: "my-theme",
  templateUrl: "../js/divdrawer/Themes/theme.template.html"
})
export class ThemeComponent implements OnInit {
  //
}

and bootstrapping it through javascript like this: window.appnamespace.platform.bootstrapModule(window.appnamespace.ThemeModule);

theme.preview component

@Component({
  selector: "theme-preview",
  templateUrl: "../theme-preview/theme-preview.component.template.html",
  styleUrls: ['../theme-preview/theme-style.less']
})

export class ThemePreview implements OnInit {
  // some code
}

theme-style.less: contains the css

@import "./theme-variable.less";

// some css

theme-variable.less: contains the less variables

@header-bg        :red;
@badge-title-bg   : #ddd;

I want to use less variables and styles in my theme-preview component to change theme dynamically.

How can I configure less in theme component only.

J.K.A.
  • 7,272
  • 25
  • 94
  • 163
  • If you don't use cli what do you use to transpile, build ect ? System.js ? Webpack ? – Yvan Oct 12 '19 at 07:51
  • 1
    Ok, so, I've saw system.js in your package.json. You need to use a plugin write for system in order to load less files. Like this one : https://github.com/systemjs/plugin-less. This package is well documented, I think you can easily reproduce their sample. – Yvan Oct 12 '19 at 07:55
  • @Yvan: Systemjs and Webpack – J.K.A. Oct 12 '19 at 10:31
  • So, you need a plugin to load less, this plugin https://github.com/systemjs/plugin-less is recommended by systemjs. – Yvan Oct 12 '19 at 10:39

1 Answers1

3

In your @Component, the property styleUrl has all the style files which need to be complied together into a single CSS file. This is however done by angular CLI.

If you intend to use CLI to generate CSS from less, go to the file called angular.json and change the value of schematics.@schematics/angular:component.style to 'less'.

This however, may not help you in dynamic (run-time) theming. For dynamic theming,

  1. import all the less file using @import statement in any 1 main file
  2. For serer side compilation, compile it using node.js server and less.js when CSS is requested. Therefore, less.js will be a production dependency in your node.js project.
  3. For client side compilation, put the main less file created in step 1 into html's head section as below. <link href="main.less" rel="stylesheet" type="text/less"/> Next, import less.js into the main.ts of angular app or use script tag for less.js in the HTML body.

In the @Component, styleUrls can be removed as there is no use of it.

Also, all the component related styles need to be wrapped in 1 class specific to the component(both HTML and less). This will ensure that you achieve the same behavior as that of angular CLI.

Hope this helps. Please comment for any more specific issue in this.

Kumar Sidharth
  • 578
  • 5
  • 13