ngx-easy-theme-switcher 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -1
- package/fesm2022/ngx-easy-theme-switcher.mjs +6 -6
- package/fesm2022/ngx-easy-theme-switcher.mjs.map +1 -1
- package/package.json +7 -6
- package/types/ngx-easy-theme-switcher.d.ts +62 -0
- package/index.d.ts +0 -5
- package/lib/theme-toggle/theme-toggle.component.d.ts +0 -27
- package/lib/theme.service.d.ts +0 -33
- package/public-api.d.ts +0 -4
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# NGX Easy Theme Switcher
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/ngx-easy-theme-switcher)
|
|
4
|
+
[](https://angular.dev)
|
|
5
|
+
|
|
3
6
|
Angular library for easy theme switching (light/dark) with customizable toggle icons.
|
|
4
7
|
|
|
5
8
|
## Features
|
|
@@ -9,6 +12,8 @@ Angular library for easy theme switching (light/dark) with customizable toggle i
|
|
|
9
12
|
- **Customizable icon** — default FontAwesome, with support for any icon font or custom SVG
|
|
10
13
|
- **Standalone** — compatible with Angular standalone components
|
|
11
14
|
- **Minimal** — just a service and a toggle component
|
|
15
|
+
- **Angular 21** — built and tested with Angular 21.2+
|
|
16
|
+
- **Tested** — unit tests (Jasmine + Karma) and e2e tests (Playwright)
|
|
12
17
|
|
|
13
18
|
## Installation
|
|
14
19
|
|
|
@@ -201,8 +206,28 @@ this.themeService.currentTheme$.subscribe(theme => {
|
|
|
201
206
|
| `lightIcon` | `'fa-sun'` | Icon name/class for the first theme |
|
|
202
207
|
| `darkIcon` | `'fa-moon'` | Icon name/class for the second theme |
|
|
203
208
|
|
|
209
|
+
## Testing
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Unit tests (library)
|
|
213
|
+
npm run test:lib
|
|
214
|
+
|
|
215
|
+
# Unit tests (demo app)
|
|
216
|
+
npm run test:app
|
|
217
|
+
|
|
218
|
+
# All unit tests in CI mode (single run, headless)
|
|
219
|
+
npm run test:ci
|
|
220
|
+
|
|
221
|
+
# E2E tests (Playwright)
|
|
222
|
+
npm run e2e
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Changelog
|
|
226
|
+
|
|
227
|
+
See [CHANGELOG.md](./CHANGELOG.md) for the full release history.
|
|
228
|
+
|
|
204
229
|
## License
|
|
205
230
|
|
|
206
|
-
Copyright (c)
|
|
231
|
+
Copyright (c) 2026 **Gennady Artamonov**
|
|
207
232
|
|
|
208
233
|
All use is free. Redistribution or resale of the library itself as a paid product is prohibited. See [LICENSE.md](./LICENSE.md) for full terms.
|
|
@@ -68,10 +68,10 @@ class ThemeService {
|
|
|
68
68
|
// localStorage not available
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
72
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
71
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeService, deps: [{ token: THEME_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
72
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeService, providedIn: 'root' });
|
|
73
73
|
}
|
|
74
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeService, decorators: [{
|
|
75
75
|
type: Injectable,
|
|
76
76
|
args: [{
|
|
77
77
|
providedIn: 'root',
|
|
@@ -135,8 +135,8 @@ class ThemeToggleComponent {
|
|
|
135
135
|
this.displayIconText = '';
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
139
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
138
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeToggleComponent, deps: [{ token: ThemeService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
139
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ThemeToggleComponent, isStandalone: true, selector: "ets-theme-toggle", inputs: { iconFont: "iconFont", svgIcon: "svgIcon", lightIcon: "lightIcon", darkIcon: "darkIcon" }, ngImport: i0, template: `
|
|
140
140
|
<button
|
|
141
141
|
class="ets-toggle-btn"
|
|
142
142
|
(click)="toggle()"
|
|
@@ -154,7 +154,7 @@ class ThemeToggleComponent {
|
|
|
154
154
|
</button>
|
|
155
155
|
`, isInline: true, styles: [".ets-toggle-btn{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;padding:8px;border-radius:50%;transition:background-color .3s,color .3s;color:inherit;font-size:1.25rem;line-height:1}.ets-toggle-btn:hover{background-color:#80808026}.ets-icon{display:inline-flex;align-items:center;justify-content:center}.ets-icon--svg{line-height:0}.ets-icon--svg ::ng-deep svg{width:1.25rem;height:1.25rem;fill:currentColor}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
156
156
|
}
|
|
157
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeToggleComponent, decorators: [{
|
|
158
158
|
type: Component,
|
|
159
159
|
args: [{ selector: 'ets-theme-toggle', standalone: true, imports: [NgClass], template: `
|
|
160
160
|
<button
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-easy-theme-switcher.mjs","sources":["../../../projects/ngx-easy-theme-switcher/src/lib/theme.service.ts","../../../projects/ngx-easy-theme-switcher/src/lib/theme-toggle/theme-toggle.component.ts","../../../projects/ngx-easy-theme-switcher/src/public-api.ts","../../../projects/ngx-easy-theme-switcher/src/ngx-easy-theme-switcher.ts"],"sourcesContent":["import { Injectable, Inject, Optional, InjectionToken } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport interface ThemeConfig {\n /** Names of the two themes, e.g. ['light', 'dark'] */\n themes?: [string, string];\n /** CSS attribute/class to set on the document element */\n attribute?: string;\n /** Storage key for persisting theme preference */\n storageKey?: string;\n /** Default theme (index 0 or 1 from themes array) */\n defaultTheme?: string;\n}\n\nexport const THEME_CONFIG = new InjectionToken<ThemeConfig>('THEME_CONFIG');\n\nconst DEFAULT_CONFIG: ThemeConfig = {\n themes: ['light', 'dark'],\n attribute: 'data-theme',\n storageKey: 'ets-pref-theme',\n defaultTheme: 'light',\n};\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ThemeService {\n private config: ThemeConfig;\n private currentThemeSubject: BehaviorSubject<string>;\n public currentTheme$: Observable<string>;\n\n constructor(@Optional() @Inject(THEME_CONFIG) config?: ThemeConfig) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.currentThemeSubject = new BehaviorSubject<string>(\n this.getStoredTheme()\n );\n this.currentTheme$ = this.currentThemeSubject.asObservable();\n this.applyTheme(this.currentThemeSubject.value);\n }\n\n /** Get the current theme name */\n get currentTheme(): string {\n return this.currentThemeSubject.value;\n }\n\n /** Get all available theme names */\n get themes(): [string, string] {\n return this.config.themes!;\n }\n\n /** Toggle between the two configured themes */\n toggleTheme(): void {\n const [themeA, themeB] = this.config.themes!;\n const next = this.currentTheme === themeA ? themeB : themeA;\n this.setTheme(next);\n }\n\n /** Set a specific theme by name */\n setTheme(theme: string): void {\n if (!this.config.themes!.includes(theme)) {\n console.warn(\n `[EasyThemeSwitcher] Theme \"${theme}\" is not in configured themes:`,\n this.config.themes\n );\n return;\n }\n this.currentThemeSubject.next(theme);\n this.applyTheme(theme);\n this.storeTheme(theme);\n }\n\n private applyTheme(theme: string): void {\n const attr = this.config.attribute!;\n document.documentElement.setAttribute(attr, theme);\n }\n\n private getStoredTheme(): string {\n try {\n const stored = localStorage.getItem(this.config.storageKey!);\n if (stored && this.config.themes!.includes(stored)) {\n return stored;\n }\n } catch {\n // localStorage not available\n }\n return this.config.defaultTheme!;\n }\n\n private storeTheme(theme: string): void {\n try {\n localStorage.setItem(this.config.storageKey!, theme);\n } catch {\n // localStorage not available\n }\n }\n}\n","import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';\nimport { NgClass } from '@angular/common';\nimport { Subject, takeUntil } from 'rxjs';\nimport { ThemeService } from '../theme.service';\n\nexport type IconFont =\n | 'fas' // FontAwesome Solid\n | 'far' // FontAwesome Regular\n | 'fal' // FontAwesome Light\n | 'fab' // FontAwesome Brands\n | 'material-icons'\n | 'material-icons-outlined'\n | 'material-symbols-outlined'\n | 'bi' // Bootstrap Icons\n | 'pi' // PrimeIcons\n | 'ion-icon'; // Ionicons\n\n@Component({\n selector: 'ets-theme-toggle',\n standalone: true,\n imports: [NgClass],\n template: `\n <button\n class=\"ets-toggle-btn\"\n (click)=\"toggle()\"\n [attr.aria-label]=\"'Switch to ' + oppositeTheme + ' mode'\"\n type=\"button\"\n >\n @if (svgIcon) {\n <span class=\"ets-icon ets-icon--svg\" [innerHTML]=\"svgIcon\"></span>\n } @else {\n <span\n class=\"ets-icon\"\n [ngClass]=\"iconClasses\"\n >{{ displayIconText }}</span>\n }\n </button>\n `,\n styles: `\n .ets-toggle-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n transition: background-color 0.3s, color 0.3s;\n color: inherit;\n font-size: 1.25rem;\n line-height: 1;\n }\n .ets-toggle-btn:hover {\n background-color: rgba(128, 128, 128, 0.15);\n }\n .ets-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n .ets-icon--svg {\n line-height: 0;\n }\n .ets-icon--svg ::ng-deep svg {\n width: 1.25rem;\n height: 1.25rem;\n fill: currentColor;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ThemeToggleComponent implements OnInit, OnDestroy {\n /** Icon font abbreviation (e.g. 'fas', 'material-icons', 'bi') */\n @Input() iconFont?: IconFont;\n\n /** Custom SVG markup (overrides iconFont if provided) */\n @Input() svgIcon?: string;\n\n /** Icon name for the first theme (default light) */\n @Input() lightIcon?: string;\n\n /** Icon name for the second theme (default dark) */\n @Input() darkIcon?: string;\n\n protected oppositeTheme = '';\n protected iconClasses: Record<string, boolean> = {};\n protected displayIconText = '';\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private themeService: ThemeService,\n private cdr: ChangeDetectorRef,\n ) {}\n\n ngOnInit(): void {\n this.updateState(this.themeService.currentTheme);\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe((theme) => {\n this.updateState(theme);\n this.cdr.markForCheck();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n toggle(): void {\n this.themeService.toggleTheme();\n }\n\n private updateState(currentTheme: string): void {\n const [lightTheme, darkTheme] = this.themeService.themes;\n const isLight = currentTheme === lightTheme;\n\n this.oppositeTheme = currentTheme === lightTheme ? darkTheme : lightTheme;\n\n const iconName = isLight\n ? (this.darkIcon ?? 'fa-moon')\n : (this.lightIcon ?? 'fa-sun');\n\n const font = this.iconFont ?? 'fas';\n\n if (font.startsWith('material')) {\n this.iconClasses = { [font]: true };\n this.displayIconText = iconName;\n } else {\n this.iconClasses = { [font]: true, [iconName]: true };\n this.displayIconText = '';\n }\n }\n}\n","/*\r\n * Public API Surface of ngx-easy-theme-switcher\r\n */\r\n\r\nexport { ThemeService, THEME_CONFIG } from './lib/theme.service';\r\nexport type { ThemeConfig } from './lib/theme.service';\r\nexport { ThemeToggleComponent } from './lib/theme-toggle/theme-toggle.component';\r\nexport type { IconFont } from './lib/theme-toggle/theme-toggle.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ThemeService"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngx-easy-theme-switcher.mjs","sources":["../../../projects/ngx-easy-theme-switcher/src/lib/theme.service.ts","../../../projects/ngx-easy-theme-switcher/src/lib/theme-toggle/theme-toggle.component.ts","../../../projects/ngx-easy-theme-switcher/src/public-api.ts","../../../projects/ngx-easy-theme-switcher/src/ngx-easy-theme-switcher.ts"],"sourcesContent":["import { Injectable, Inject, Optional, InjectionToken } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport interface ThemeConfig {\n /** Names of the two themes, e.g. ['light', 'dark'] */\n themes?: [string, string];\n /** CSS attribute/class to set on the document element */\n attribute?: string;\n /** Storage key for persisting theme preference */\n storageKey?: string;\n /** Default theme (index 0 or 1 from themes array) */\n defaultTheme?: string;\n}\n\nexport const THEME_CONFIG = new InjectionToken<ThemeConfig>('THEME_CONFIG');\n\nconst DEFAULT_CONFIG: ThemeConfig = {\n themes: ['light', 'dark'],\n attribute: 'data-theme',\n storageKey: 'ets-pref-theme',\n defaultTheme: 'light',\n};\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ThemeService {\n private config: ThemeConfig;\n private currentThemeSubject: BehaviorSubject<string>;\n public currentTheme$: Observable<string>;\n\n constructor(@Optional() @Inject(THEME_CONFIG) config?: ThemeConfig) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.currentThemeSubject = new BehaviorSubject<string>(\n this.getStoredTheme()\n );\n this.currentTheme$ = this.currentThemeSubject.asObservable();\n this.applyTheme(this.currentThemeSubject.value);\n }\n\n /** Get the current theme name */\n get currentTheme(): string {\n return this.currentThemeSubject.value;\n }\n\n /** Get all available theme names */\n get themes(): [string, string] {\n return this.config.themes!;\n }\n\n /** Toggle between the two configured themes */\n toggleTheme(): void {\n const [themeA, themeB] = this.config.themes!;\n const next = this.currentTheme === themeA ? themeB : themeA;\n this.setTheme(next);\n }\n\n /** Set a specific theme by name */\n setTheme(theme: string): void {\n if (!this.config.themes!.includes(theme)) {\n console.warn(\n `[EasyThemeSwitcher] Theme \"${theme}\" is not in configured themes:`,\n this.config.themes\n );\n return;\n }\n this.currentThemeSubject.next(theme);\n this.applyTheme(theme);\n this.storeTheme(theme);\n }\n\n private applyTheme(theme: string): void {\n const attr = this.config.attribute!;\n document.documentElement.setAttribute(attr, theme);\n }\n\n private getStoredTheme(): string {\n try {\n const stored = localStorage.getItem(this.config.storageKey!);\n if (stored && this.config.themes!.includes(stored)) {\n return stored;\n }\n } catch {\n // localStorage not available\n }\n return this.config.defaultTheme!;\n }\n\n private storeTheme(theme: string): void {\n try {\n localStorage.setItem(this.config.storageKey!, theme);\n } catch {\n // localStorage not available\n }\n }\n}\n","import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';\nimport { NgClass } from '@angular/common';\nimport { Subject, takeUntil } from 'rxjs';\nimport { ThemeService } from '../theme.service';\n\nexport type IconFont =\n | 'fas' // FontAwesome Solid\n | 'far' // FontAwesome Regular\n | 'fal' // FontAwesome Light\n | 'fab' // FontAwesome Brands\n | 'material-icons'\n | 'material-icons-outlined'\n | 'material-symbols-outlined'\n | 'bi' // Bootstrap Icons\n | 'pi' // PrimeIcons\n | 'ion-icon'; // Ionicons\n\n@Component({\n selector: 'ets-theme-toggle',\n standalone: true,\n imports: [NgClass],\n template: `\n <button\n class=\"ets-toggle-btn\"\n (click)=\"toggle()\"\n [attr.aria-label]=\"'Switch to ' + oppositeTheme + ' mode'\"\n type=\"button\"\n >\n @if (svgIcon) {\n <span class=\"ets-icon ets-icon--svg\" [innerHTML]=\"svgIcon\"></span>\n } @else {\n <span\n class=\"ets-icon\"\n [ngClass]=\"iconClasses\"\n >{{ displayIconText }}</span>\n }\n </button>\n `,\n styles: `\n .ets-toggle-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n transition: background-color 0.3s, color 0.3s;\n color: inherit;\n font-size: 1.25rem;\n line-height: 1;\n }\n .ets-toggle-btn:hover {\n background-color: rgba(128, 128, 128, 0.15);\n }\n .ets-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n .ets-icon--svg {\n line-height: 0;\n }\n .ets-icon--svg ::ng-deep svg {\n width: 1.25rem;\n height: 1.25rem;\n fill: currentColor;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ThemeToggleComponent implements OnInit, OnDestroy {\n /** Icon font abbreviation (e.g. 'fas', 'material-icons', 'bi') */\n @Input() iconFont?: IconFont;\n\n /** Custom SVG markup (overrides iconFont if provided) */\n @Input() svgIcon?: string;\n\n /** Icon name for the first theme (default light) */\n @Input() lightIcon?: string;\n\n /** Icon name for the second theme (default dark) */\n @Input() darkIcon?: string;\n\n protected oppositeTheme = '';\n protected iconClasses: Record<string, boolean> = {};\n protected displayIconText = '';\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private themeService: ThemeService,\n private cdr: ChangeDetectorRef,\n ) {}\n\n ngOnInit(): void {\n this.updateState(this.themeService.currentTheme);\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe((theme) => {\n this.updateState(theme);\n this.cdr.markForCheck();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n toggle(): void {\n this.themeService.toggleTheme();\n }\n\n private updateState(currentTheme: string): void {\n const [lightTheme, darkTheme] = this.themeService.themes;\n const isLight = currentTheme === lightTheme;\n\n this.oppositeTheme = currentTheme === lightTheme ? darkTheme : lightTheme;\n\n const iconName = isLight\n ? (this.darkIcon ?? 'fa-moon')\n : (this.lightIcon ?? 'fa-sun');\n\n const font = this.iconFont ?? 'fas';\n\n if (font.startsWith('material')) {\n this.iconClasses = { [font]: true };\n this.displayIconText = iconName;\n } else {\n this.iconClasses = { [font]: true, [iconName]: true };\n this.displayIconText = '';\n }\n }\n}\n","/*\r\n * Public API Surface of ngx-easy-theme-switcher\r\n */\r\n\r\nexport { ThemeService, THEME_CONFIG } from './lib/theme.service';\r\nexport type { ThemeConfig } from './lib/theme.service';\r\nexport { ThemeToggleComponent } from './lib/theme-toggle/theme-toggle.component';\r\nexport type { IconFont } from './lib/theme-toggle/theme-toggle.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ThemeService"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-easy-theme-switcher",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A lightweight Angular service and component for seamless dark/light theme switching. Supports FontAwesome, Material Icons, Bootstrap Icons, custom SVG icons, and popular icon fonts out of the box. Persistent theme selection with localStorage.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -30,22 +30,23 @@
|
|
|
30
30
|
"url": "https://github.com/cyclon-b/ngx-easy-theme-switcher.git"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@angular/common": "^
|
|
34
|
-
"@angular/core": "^
|
|
33
|
+
"@angular/common": "^21.2.0",
|
|
34
|
+
"@angular/core": "^21.2.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"tslib": "^2.3.0"
|
|
38
38
|
},
|
|
39
39
|
"sideEffects": false,
|
|
40
40
|
"module": "fesm2022/ngx-easy-theme-switcher.mjs",
|
|
41
|
-
"typings": "
|
|
41
|
+
"typings": "types/ngx-easy-theme-switcher.d.ts",
|
|
42
42
|
"exports": {
|
|
43
43
|
"./package.json": {
|
|
44
44
|
"default": "./package.json"
|
|
45
45
|
},
|
|
46
46
|
".": {
|
|
47
|
-
"types": "./
|
|
47
|
+
"types": "./types/ngx-easy-theme-switcher.d.ts",
|
|
48
48
|
"default": "./fesm2022/ngx-easy-theme-switcher.mjs"
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
},
|
|
51
|
+
"type": "module"
|
|
51
52
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
interface ThemeConfig {
|
|
6
|
+
/** Names of the two themes, e.g. ['light', 'dark'] */
|
|
7
|
+
themes?: [string, string];
|
|
8
|
+
/** CSS attribute/class to set on the document element */
|
|
9
|
+
attribute?: string;
|
|
10
|
+
/** Storage key for persisting theme preference */
|
|
11
|
+
storageKey?: string;
|
|
12
|
+
/** Default theme (index 0 or 1 from themes array) */
|
|
13
|
+
defaultTheme?: string;
|
|
14
|
+
}
|
|
15
|
+
declare const THEME_CONFIG: InjectionToken<ThemeConfig>;
|
|
16
|
+
declare class ThemeService {
|
|
17
|
+
private config;
|
|
18
|
+
private currentThemeSubject;
|
|
19
|
+
currentTheme$: Observable<string>;
|
|
20
|
+
constructor(config?: ThemeConfig);
|
|
21
|
+
/** Get the current theme name */
|
|
22
|
+
get currentTheme(): string;
|
|
23
|
+
/** Get all available theme names */
|
|
24
|
+
get themes(): [string, string];
|
|
25
|
+
/** Toggle between the two configured themes */
|
|
26
|
+
toggleTheme(): void;
|
|
27
|
+
/** Set a specific theme by name */
|
|
28
|
+
setTheme(theme: string): void;
|
|
29
|
+
private applyTheme;
|
|
30
|
+
private getStoredTheme;
|
|
31
|
+
private storeTheme;
|
|
32
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ThemeService, [{ optional: true; }]>;
|
|
33
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ThemeService>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type IconFont = 'fas' | 'far' | 'fal' | 'fab' | 'material-icons' | 'material-icons-outlined' | 'material-symbols-outlined' | 'bi' | 'pi' | 'ion-icon';
|
|
37
|
+
declare class ThemeToggleComponent implements OnInit, OnDestroy {
|
|
38
|
+
private themeService;
|
|
39
|
+
private cdr;
|
|
40
|
+
/** Icon font abbreviation (e.g. 'fas', 'material-icons', 'bi') */
|
|
41
|
+
iconFont?: IconFont;
|
|
42
|
+
/** Custom SVG markup (overrides iconFont if provided) */
|
|
43
|
+
svgIcon?: string;
|
|
44
|
+
/** Icon name for the first theme (default light) */
|
|
45
|
+
lightIcon?: string;
|
|
46
|
+
/** Icon name for the second theme (default dark) */
|
|
47
|
+
darkIcon?: string;
|
|
48
|
+
protected oppositeTheme: string;
|
|
49
|
+
protected iconClasses: Record<string, boolean>;
|
|
50
|
+
protected displayIconText: string;
|
|
51
|
+
private destroy$;
|
|
52
|
+
constructor(themeService: ThemeService, cdr: ChangeDetectorRef);
|
|
53
|
+
ngOnInit(): void;
|
|
54
|
+
ngOnDestroy(): void;
|
|
55
|
+
toggle(): void;
|
|
56
|
+
private updateState;
|
|
57
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ThemeToggleComponent, never>;
|
|
58
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ThemeToggleComponent, "ets-theme-toggle", never, { "iconFont": { "alias": "iconFont"; "required": false; }; "svgIcon": { "alias": "svgIcon"; "required": false; }; "lightIcon": { "alias": "lightIcon"; "required": false; }; "darkIcon": { "alias": "darkIcon"; "required": false; }; }, {}, never, never, true, never>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { THEME_CONFIG, ThemeService, ThemeToggleComponent };
|
|
62
|
+
export type { IconFont, ThemeConfig };
|
package/index.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';
|
|
2
|
-
import { ThemeService } from '../theme.service';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export type IconFont = 'fas' | 'far' | 'fal' | 'fab' | 'material-icons' | 'material-icons-outlined' | 'material-symbols-outlined' | 'bi' | 'pi' | 'ion-icon';
|
|
5
|
-
export declare class ThemeToggleComponent implements OnInit, OnDestroy {
|
|
6
|
-
private themeService;
|
|
7
|
-
private cdr;
|
|
8
|
-
/** Icon font abbreviation (e.g. 'fas', 'material-icons', 'bi') */
|
|
9
|
-
iconFont?: IconFont;
|
|
10
|
-
/** Custom SVG markup (overrides iconFont if provided) */
|
|
11
|
-
svgIcon?: string;
|
|
12
|
-
/** Icon name for the first theme (default light) */
|
|
13
|
-
lightIcon?: string;
|
|
14
|
-
/** Icon name for the second theme (default dark) */
|
|
15
|
-
darkIcon?: string;
|
|
16
|
-
protected oppositeTheme: string;
|
|
17
|
-
protected iconClasses: Record<string, boolean>;
|
|
18
|
-
protected displayIconText: string;
|
|
19
|
-
private destroy$;
|
|
20
|
-
constructor(themeService: ThemeService, cdr: ChangeDetectorRef);
|
|
21
|
-
ngOnInit(): void;
|
|
22
|
-
ngOnDestroy(): void;
|
|
23
|
-
toggle(): void;
|
|
24
|
-
private updateState;
|
|
25
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<ThemeToggleComponent, never>;
|
|
26
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ThemeToggleComponent, "ets-theme-toggle", never, { "iconFont": { "alias": "iconFont"; "required": false; }; "svgIcon": { "alias": "svgIcon"; "required": false; }; "lightIcon": { "alias": "lightIcon"; "required": false; }; "darkIcon": { "alias": "darkIcon"; "required": false; }; }, {}, never, never, true, never>;
|
|
27
|
-
}
|
package/lib/theme.service.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { InjectionToken } from '@angular/core';
|
|
2
|
-
import { Observable } from 'rxjs';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export interface ThemeConfig {
|
|
5
|
-
/** Names of the two themes, e.g. ['light', 'dark'] */
|
|
6
|
-
themes?: [string, string];
|
|
7
|
-
/** CSS attribute/class to set on the document element */
|
|
8
|
-
attribute?: string;
|
|
9
|
-
/** Storage key for persisting theme preference */
|
|
10
|
-
storageKey?: string;
|
|
11
|
-
/** Default theme (index 0 or 1 from themes array) */
|
|
12
|
-
defaultTheme?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare const THEME_CONFIG: InjectionToken<ThemeConfig>;
|
|
15
|
-
export declare class ThemeService {
|
|
16
|
-
private config;
|
|
17
|
-
private currentThemeSubject;
|
|
18
|
-
currentTheme$: Observable<string>;
|
|
19
|
-
constructor(config?: ThemeConfig);
|
|
20
|
-
/** Get the current theme name */
|
|
21
|
-
get currentTheme(): string;
|
|
22
|
-
/** Get all available theme names */
|
|
23
|
-
get themes(): [string, string];
|
|
24
|
-
/** Toggle between the two configured themes */
|
|
25
|
-
toggleTheme(): void;
|
|
26
|
-
/** Set a specific theme by name */
|
|
27
|
-
setTheme(theme: string): void;
|
|
28
|
-
private applyTheme;
|
|
29
|
-
private getStoredTheme;
|
|
30
|
-
private storeTheme;
|
|
31
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<ThemeService, [{ optional: true; }]>;
|
|
32
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<ThemeService>;
|
|
33
|
-
}
|
package/public-api.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { ThemeService, THEME_CONFIG } from './lib/theme.service';
|
|
2
|
-
export type { ThemeConfig } from './lib/theme.service';
|
|
3
|
-
export { ThemeToggleComponent } from './lib/theme-toggle/theme-toggle.component';
|
|
4
|
-
export type { IconFont } from './lib/theme-toggle/theme-toggle.component';
|