@rb-mwindh/ngx-theme-manager - v1.0.1

ngx-theme-manager

@rb-mwindh/ngx-theme-manager provides the basics tools for a robust theme-switcher implementation.

This package does not provide ready-made visual components, but only supports their implementation by providing the necessary services and tools.


sponsors License latest release

open issues open pr

nodejs angular


Table of Contents

How it works

This implementation is based on the regular way Angular loads styles for components. Since theme styles are usually global styles, theme components will normally use ViewEncapsulation.None.

Since Angular does not provide a direct way to access the <style> element associated with a component, the @rb-mwindh/ngx-theme-manager applies a little trick: Style elements provided as themes should carry annotations in the form of predefined CSS comments. These annotations are searched throughout all <style> elements of the application using regular expressions and are registered in the theme registry. Also, an additional attribute (data-theme="<id>") is added to the corresponding style elements, which is used as a query selector.

Hereafter, the ThemeService leverages the media attribute to enable or disable the styles of a theme. For inactive themes, the media="none" attribute is added to the associated <style> element. For active themes, the media attribute of the associated <style> element is simply removed again.

Getting Started

Install the package

npm install ngx-theme-manager --save

Implement your theme stylesheets

@rb-mwindh/ngx-theme-manager identifies your stylesheets (css/scss/...) as themes through annotations in css comments. To prevent your annotations from being disposed at build time by minification, you should use the css comment format /*! ... */.

... By default, multi-line comments be stripped from the compiled CSS in compressed mode. If a comment begins with /*!, though, it will always be included in the CSS output. ...

from https://sass-lang.com/documentation/syntax/comments

Known annotations are:

  • @@id - required, any character until end-of-line
  • @@displayName - optional, defaults to <@@id>, any character until end-of-line
  • @@description - optional, any character until end-of-line
  • @@default - optional, no value, value is true when given, or false when omitted
/*!
* @@id my-theme-id
* @@displayName My Fantastic Theme
* @@description This is my fantastic theme with magic colors
* @@default
*/

// add all your theme styles below this line, e.g.
@import "@angular/material/prebuilt-themes/indigo-pink.css";
@import "some-other-library/theme.css";

Loading your theme stylesheets

By using an Angular component to load your stylesheets, you make the Angular compiler pick up and compile your stylesheets automatically.

@Component({
selector: 'app-themes',
template: '', // no template needed
styleUrls: [
'assets/themes/theme-a.scss',
'assets/themes/theme-b.scss',
'assets/themes/theme-c.scss',
], // load all theme stylesheets here
encapsulation: ViewEncapsulation.None, // make the styles global
})
export class AppThemesComponent { /* no implementation needed */ }

This way, loading the theme stylesheets is easily done by using your AppThemesComponent, preferably at the top of your AppComponent.

@Component({
selector: 'app-root',
template: `
<app-themes></app-themes>

<!-- you app template here -->
`,
})
export class AppComponent() { ... }

Implement your theme-picker component

The desired look-and-feel of your visual theme-picker component usually is very specific for the respective project. Thus, I've decided not to implement any visual stuff, but instead provide you with the required data.

Assuming, you've implemented a theme picker component named app-theme-picker, you would provide it with the available themes, the current theme and a theme selection callback like this:

@Component({
selector: 'app-root',
template: `
<app-theme-picker
[themes]="themeService.themes$ | async"
[currentTheme]="themeService.currentTheme$ | async"
(select)="themeService.selectTheme($event)"
></app-theme-picker>

<!-- you app template here -->
`,
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(public readonly themeService: ThemeService) {
}
}

Building and Testing

  1. Clone the repository
git clone https://github.com/rb-mwindh/ngx-theme-manager.git <workspace>
cd <workspace>
  1. Initialize the workspace

The init script installs all dependencies and sets up the pre-commit hooks.

This is mandatory to guarantee the code style and quality!

npm run init
  1. Run the demo app
npm run start
  1. Build the library
npm run build
  1. Run the unit tests
npm run test

Contribution Guidelines

Thank you for your interest in contributing to this library.

Please read the Contribution Guidelines

Get help

Please check my wiki::faq and wiki::troubleshooting wiki page first.

If this doesn't answer your question, you may post a question to the issue tracker.

About

Maintainers

Contributors

  • none ;(

3rd Party Licenses

Name License Type
@angular/animations MIT Dependency
@angular/cdk MIT Dependency
@angular/common MIT Dependency
@angular/compiler MIT Dependency
@angular/core MIT Dependency
@angular/forms MIT Dependency
@angular/platform-browser-dynamic MIT Dependency
@angular/platform-browser MIT Dependency
@angular/router MIT Dependency
entities BSD-2-Clause Dependency
material-icons Apache-2.0 Dependency
ngx-theme-manager MIT Dependency
parse5 MIT Dependency
rxjs Apache-2.0 Dependency
tslib 0BSD Dependency
zone.js MIT Dependency

License

License