Search code examples
angulartypescriptsassnativescriptnativescript-angular

Nativescript Angular, changing theme


I am building a NativeScript application with Angular and I am trying to implement Theme switching, but I cannot get it to work with Webpack bundling.

My versions:

  • Angular 7.2.12
  • Nativescript-angular 7.2.3
  • Nativescript-themes 2.0.0
  • TypeScript 3.2.2

I followed the turtorials for implementing the feature in an Angular project: here and here. But these are for non-webpack (without the --bundle flag) builds. With the bundle flag (and the change described here) the switching no longer works and an error is thrown on each switch:

JS: ~/assets/themes/dark.scss
JS: Error: Css styling failed: Error: undefined:1:26: missing '{'

The theme file (located in ~/assets/themes/dark.scss)

ActionBar {
  background-color: #B20000;
  color: #FFFFFF;
}

.btn-primary {
  background-color: #B20000;
  color: #000000;
}

The function applyThemeCss() should extract the styling from the project, but it doesn't because of an error. The test project can be found here, on StackBlitz (I didn't use the Nativescript playground, since it doesn't have a package.json and the assets folder )


Solution

  • applyThemeCss() expects CSS text not path to file. In the example code he uses a require statement to read the file then passing the CSS text to the method.

    Also in your case if you want multiple themes to be applied dynamically, then you may have to modify your webpack.config.js to ship the CSS files to app bundle, something like below.

            // Copy assets to out dir. Add your own globs as needed.
            new CopyWebpackPlugin([
                { from: { glob: "assets/**" } },
                { from: { glob: "fonts/**" } },
                { from: { glob: "**/*.jpg" } },
                { from: { glob: "**/*.png" } },
            ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
    

    Then use the applyTheme() method to pass the file name

    Themes.applyTheme(ThemeService.THEME_PATH + theme);
    

    If you like to use applyThemeCss() then read the file and pass the content

    Themes.applyThemeCSS(knownFolders.currentApp().getFile('assets/themes/' + theme).readTextSync(), theme);