13.0.5 • Published 2 years ago

@ngbasics/theme-selector v13.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

@ngbasics/theme-selector

Switch global styles at runtime.

demo


Installation

npm i @ngbasics/theme-selector

Preparation

Build your stylesheets:

// src/themes/dark.scss
body {
  background-color: black;
  color: white;
}

// src/themes/light.scss
body {
  background-color: white;
  color: black;
}

Add to angular.json (dev-server needs to be restarted):

"styles": [
  "src/styles.scss",
  {
    "bundleName": "dark", // <- produces 'dark.css'
    "input": "src/themes/dark.scss",
    "inject": false
  },
  {
    "bundleName": "light",
    "input": "src/themes/light.scss",
    "inject": false
  }
]

Usage

Configure the Module:

Add a link-tag to your index.html and provide a selector to the config.

<!-- index.html -->
<link rel="stylesheet" id="theme" href="dark.css" />
// app.module.ts
const themeConfig: ThemeSelectorConfig = {
  selector: () => querySelector('#theme'),
};

@NgModule({
  imports: [ThemeSelectorModule.forRoot(themeConfig)],
})
export class AppModule {}

Alternatively, if it doesn't matter whether the initial style is loaded asynchronously or not, you can provide it's name in the config and let the service inject it into your html.

type Theme = 'light' | 'dark';

@NgModule({
  imports: [ThemeSelectorModule.forRoot<Theme>({ initialTheme: 'dark' })],
})
export class AppModule {}

Use the service:

@Component({
  selector: 'app-theme',
  template: `<div>{{ themeService.theme$ | async }}</div>
    <button (click)="themeService.selectTheme('dark')">dark</button>
    <button (click)="themeService.selectTheme('light')">light</button>`,
})
export class ThemeComponent {
  constructor(public themeService: ThemeSelectorService<Theme>) {}
}

Persistence

By default the selected theme is NOT persisted.

If you want to persist the selection provide a storage to the config:

const themeConfig: ThemeSelectorConfig = {
  storage: localStorage,
};

The storage must implement the Storage interface.

OS light/dark listener

You can select a theme based on whether the user's operating system is light or dark by listening to osIsDark$:

@Component({
  selector: 'app-theme',
  templateUrl: './theme.component.html',
  styleUrls: ['./theme.component.scss'],
})
export class ThemeComponent {
  constructor(themeService: ThemeSelectorService<Theme>) {
    themeService.osIsDark$
      // respect user selected theme on reload
      .pipe(skip(localStorage.getItem(THEME_KEY) ? 1 : 0))
      .subscribe(dark => themeService.selectTheme(dark ? 'dark' : 'light'));
  }
}
13.0.5

2 years ago

13.0.2

2 years ago

13.0.3

2 years ago

13.0.0

2 years ago

12.2.4

2 years ago

12.2.3

2 years ago

12.2.2

2 years ago

12.2.1

2 years ago

12.2.0

2 years ago