@skyux/theme 12.0.0-alpha.8 → 12.0.0-beta.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/css/sky.css +14 -3
- package/css/themes/modern/styles.css +53 -59
- package/fesm2022/skyux-theme.mjs +231 -115
- package/fesm2022/skyux-theme.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/theming/theme-brand.d.ts +18 -0
- package/lib/theming/theme-settings.d.ts +3 -1
- package/package.json +13 -16
- package/scss/_compat/_variables.scss +2 -2
- package/documentation.json +0 -4610
package/fesm2022/skyux-theme.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, Optional,
|
|
2
|
+
import { Injectable, Optional, Input, Directive, NgModule, inject, ChangeDetectorRef, HostBinding, NgZone, DestroyRef, makeEnvironmentProviders, provideAppInitializer, RendererFactory2 } from '@angular/core';
|
|
3
3
|
import { getIconManifest } from '@skyux/icons';
|
|
4
4
|
import FontFaceObserver from 'fontfaceobserver';
|
|
5
5
|
import { take, takeUntil } from 'rxjs/operators';
|
|
@@ -18,16 +18,62 @@ class SkyThemeIconManifestService {
|
|
|
18
18
|
getManifest() {
|
|
19
19
|
return getIconManifest();
|
|
20
20
|
}
|
|
21
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
22
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
21
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeIconManifestService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
22
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeIconManifestService, providedIn: 'root' }); }
|
|
23
23
|
}
|
|
24
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
24
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeIconManifestService, decorators: [{
|
|
25
25
|
type: Injectable,
|
|
26
26
|
args: [{
|
|
27
27
|
providedIn: 'root',
|
|
28
28
|
}]
|
|
29
29
|
}] });
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Defines properties of a SKY UX theme mode.
|
|
33
|
+
*/
|
|
34
|
+
class SkyThemeMode {
|
|
35
|
+
/**
|
|
36
|
+
* The preset themes available in SKY UX.
|
|
37
|
+
*/
|
|
38
|
+
static { this.presets = {
|
|
39
|
+
light: new SkyThemeMode('light', 'sky-theme-mode-light'),
|
|
40
|
+
dark: new SkyThemeMode('dark', 'sky-theme-mode-dark'),
|
|
41
|
+
}; }
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new theme mode.
|
|
44
|
+
* @param name The name of the theme mode.
|
|
45
|
+
* @param hostClass The class on the host element which child components should reference when
|
|
46
|
+
* adjusting for a specified theme mode.
|
|
47
|
+
*/
|
|
48
|
+
constructor(name, hostClass) {
|
|
49
|
+
this.name = name;
|
|
50
|
+
this.hostClass = hostClass;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Defines properties of SKY UX theme spacing.
|
|
56
|
+
*/
|
|
57
|
+
class SkyThemeSpacing {
|
|
58
|
+
/**
|
|
59
|
+
* The preset spacing available in SKY UX.
|
|
60
|
+
*/
|
|
61
|
+
static { this.presets = {
|
|
62
|
+
standard: new SkyThemeSpacing('standard', 'sky-theme-spacing-standard'),
|
|
63
|
+
compact: new SkyThemeSpacing('compact', 'sky-theme-spacing-compact'),
|
|
64
|
+
}; }
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new theme spacing.
|
|
67
|
+
* @param name The name of the theme spacing.
|
|
68
|
+
* @param hostClass The class on the host element which child components should reference when
|
|
69
|
+
* adjusting for a specified theme spacing.
|
|
70
|
+
*/
|
|
71
|
+
constructor(name, hostClass) {
|
|
72
|
+
this.name = name;
|
|
73
|
+
this.hostClass = hostClass;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
31
77
|
/**
|
|
32
78
|
* Provides methods for updating and handling changes to the current theme.
|
|
33
79
|
*/
|
|
@@ -39,6 +85,7 @@ class SkyThemeService {
|
|
|
39
85
|
return this.#_settingsObs;
|
|
40
86
|
}
|
|
41
87
|
#current;
|
|
88
|
+
#brandLinkElement;
|
|
42
89
|
#hostEl;
|
|
43
90
|
#renderer;
|
|
44
91
|
#settings;
|
|
@@ -76,6 +123,7 @@ class SkyThemeService {
|
|
|
76
123
|
this.#applyThemeClass(previous, settings, 'theme');
|
|
77
124
|
this.#applyThemeClass(previous, settings, 'mode', 'supportedModes');
|
|
78
125
|
this.#applyThemeClass(previous, settings, 'spacing', 'supportedSpacing');
|
|
126
|
+
this.#applyThemeClass(previous, settings, 'brand');
|
|
79
127
|
this.#settings.next({
|
|
80
128
|
currentSettings: settings,
|
|
81
129
|
previousSettings: previous,
|
|
@@ -84,29 +132,82 @@ class SkyThemeService {
|
|
|
84
132
|
}
|
|
85
133
|
#applyThemeClass(previous, current, prop, supportedProp) {
|
|
86
134
|
const currentSetting = current[prop];
|
|
87
|
-
const previousClass = previous?.[prop]
|
|
88
|
-
const currentClass = currentSetting
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
this.#
|
|
135
|
+
const previousClass = previous?.[prop]?.hostClass;
|
|
136
|
+
const currentClass = currentSetting?.hostClass;
|
|
137
|
+
if (!previousClass || previousClass !== currentClass) {
|
|
138
|
+
this.#updateHostClass(prop, previousClass, currentClass, currentSetting, current, supportedProp);
|
|
139
|
+
if (prop === 'brand') {
|
|
140
|
+
this.#updateBrandStylesheet(current.brand, previous?.brand);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
#updateBrandStylesheet(currentBrand, previousBrand) {
|
|
145
|
+
if (currentBrand &&
|
|
146
|
+
currentBrand.name !== 'blackbaud' &&
|
|
147
|
+
previousBrand !== currentBrand) {
|
|
148
|
+
this.#addBrandStylesheet(currentBrand);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.#removeBrandStylesheet();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
#updateHostClass(prop, previousClass, currentClass, currentSetting, current, supportedProp) {
|
|
155
|
+
if (previousClass) {
|
|
156
|
+
this.#removeHostClass(previousClass);
|
|
157
|
+
}
|
|
158
|
+
if (prop === 'brand') {
|
|
159
|
+
if (currentClass && !previousClass) {
|
|
160
|
+
this.#addHostClass('sky-theme-brand-base');
|
|
93
161
|
}
|
|
94
|
-
if (!
|
|
95
|
-
|
|
96
|
-
this.#addHostClass(currentClass);
|
|
162
|
+
else if (!currentClass && previousClass) {
|
|
163
|
+
this.#removeHostClass('sky-theme-brand-base');
|
|
97
164
|
}
|
|
98
165
|
}
|
|
166
|
+
if (currentClass &&
|
|
167
|
+
this.#isSupportedProperty(currentSetting, current, supportedProp)) {
|
|
168
|
+
this.#addHostClass(currentClass);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
#addBrandStylesheet(brand) {
|
|
172
|
+
if (brand.name !== 'blackbaud') {
|
|
173
|
+
const cssPath = `https://sky.blackbaudcdn.net/static/skyux-brand-${brand.name}/${brand.version}/assets/scss/${brand.name}.css`;
|
|
174
|
+
// Create a link element via Angular's renderer to avoid SSR troubles
|
|
175
|
+
this.#brandLinkElement = this.#getRenderer().createElement('link');
|
|
176
|
+
// Add the style to the head section
|
|
177
|
+
this.#getRenderer().appendChild(this.#hostEl, this.#brandLinkElement);
|
|
178
|
+
// Set type of the link item and path to the css file
|
|
179
|
+
this.#getRenderer().setProperty(this.#brandLinkElement, 'rel', 'stylesheet');
|
|
180
|
+
this.#getRenderer().setProperty(this.#brandLinkElement, 'href', cssPath);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
#removeBrandStylesheet() {
|
|
184
|
+
if (this.#brandLinkElement) {
|
|
185
|
+
this.#getRenderer().removeChild(this.#hostEl, this.#brandLinkElement);
|
|
186
|
+
this.#brandLinkElement = undefined;
|
|
187
|
+
}
|
|
99
188
|
}
|
|
100
189
|
#addHostClass(className) {
|
|
101
|
-
this.#
|
|
190
|
+
this.#getRenderer().addClass(this.#hostEl, className);
|
|
102
191
|
}
|
|
103
192
|
#removeHostClass(className) {
|
|
104
|
-
this.#
|
|
193
|
+
this.#getRenderer().removeClass(this.#hostEl, className);
|
|
105
194
|
}
|
|
106
|
-
|
|
107
|
-
|
|
195
|
+
#getRenderer() {
|
|
196
|
+
if (!this.#renderer) {
|
|
197
|
+
throw new Error('Renderer is not initialized. Have you called the theme service `init` method?');
|
|
198
|
+
}
|
|
199
|
+
return this.#renderer;
|
|
200
|
+
}
|
|
201
|
+
#isSupportedProperty(currentSetting, current, supportedProp) {
|
|
202
|
+
return (!supportedProp ||
|
|
203
|
+
((currentSetting instanceof SkyThemeMode ||
|
|
204
|
+
currentSetting instanceof SkyThemeSpacing) &&
|
|
205
|
+
current.theme[supportedProp].includes(currentSetting)));
|
|
206
|
+
}
|
|
207
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
208
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeService }); }
|
|
108
209
|
}
|
|
109
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
210
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeService, decorators: [{
|
|
110
211
|
type: Injectable
|
|
111
212
|
}], ctorParameters: () => [] });
|
|
112
213
|
|
|
@@ -151,10 +252,10 @@ class SkyAppStyleLoader {
|
|
|
151
252
|
});
|
|
152
253
|
});
|
|
153
254
|
}
|
|
154
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
155
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
255
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyAppStyleLoader, deps: [{ token: SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
256
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyAppStyleLoader, providedIn: 'root' }); }
|
|
156
257
|
}
|
|
157
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
258
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyAppStyleLoader, decorators: [{
|
|
158
259
|
type: Injectable,
|
|
159
260
|
args: [{
|
|
160
261
|
providedIn: 'root',
|
|
@@ -261,10 +362,10 @@ class SkyThemeClassDirective {
|
|
|
261
362
|
});
|
|
262
363
|
}
|
|
263
364
|
}
|
|
264
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
265
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.
|
|
365
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeClassDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
366
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.1", type: SkyThemeClassDirective, isStandalone: false, selector: "[skyThemeClass]", inputs: { class: "class", skyThemeClass: "skyThemeClass" }, ngImport: i0 }); }
|
|
266
367
|
}
|
|
267
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
368
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeClassDirective, decorators: [{
|
|
268
369
|
type: Directive,
|
|
269
370
|
args: [{
|
|
270
371
|
selector: '[skyThemeClass]',
|
|
@@ -332,10 +433,10 @@ class SkyThemeIfDirective {
|
|
|
332
433
|
this.#hasView = false;
|
|
333
434
|
}
|
|
334
435
|
}
|
|
335
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
336
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.
|
|
436
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeIfDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
437
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.1", type: SkyThemeIfDirective, isStandalone: false, selector: "[skyThemeIf]", inputs: { skyThemeIf: "skyThemeIf" }, ngImport: i0 }); }
|
|
337
438
|
}
|
|
338
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
439
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeIfDirective, decorators: [{
|
|
339
440
|
type: Directive,
|
|
340
441
|
args: [{
|
|
341
442
|
selector: '[skyThemeIf]',
|
|
@@ -347,52 +448,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
347
448
|
type: Input
|
|
348
449
|
}] } });
|
|
349
450
|
|
|
350
|
-
/**
|
|
351
|
-
* Defines properties of a SKY UX theme mode.
|
|
352
|
-
*/
|
|
353
|
-
class SkyThemeMode {
|
|
354
|
-
/**
|
|
355
|
-
* The preset themes available in SKY UX.
|
|
356
|
-
*/
|
|
357
|
-
static { this.presets = {
|
|
358
|
-
light: new SkyThemeMode('light', 'sky-theme-mode-light'),
|
|
359
|
-
dark: new SkyThemeMode('dark', 'sky-theme-mode-dark'),
|
|
360
|
-
}; }
|
|
361
|
-
/**
|
|
362
|
-
* Creates a new theme mode.
|
|
363
|
-
* @param name The name of the theme mode.
|
|
364
|
-
* @param hostClass The class on the host element which child components should reference when
|
|
365
|
-
* adjusting for a specified theme mode.
|
|
366
|
-
*/
|
|
367
|
-
constructor(name, hostClass) {
|
|
368
|
-
this.name = name;
|
|
369
|
-
this.hostClass = hostClass;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Defines properties of SKY UX theme spacing.
|
|
375
|
-
*/
|
|
376
|
-
class SkyThemeSpacing {
|
|
377
|
-
/**
|
|
378
|
-
* The preset spacing available in SKY UX.
|
|
379
|
-
*/
|
|
380
|
-
static { this.presets = {
|
|
381
|
-
standard: new SkyThemeSpacing('standard', 'sky-theme-spacing-standard'),
|
|
382
|
-
compact: new SkyThemeSpacing('compact', 'sky-theme-spacing-compact'),
|
|
383
|
-
}; }
|
|
384
|
-
/**
|
|
385
|
-
* Creates a new theme spacing.
|
|
386
|
-
* @param name The name of the theme spacing.
|
|
387
|
-
* @param hostClass The class on the host element which child components should reference when
|
|
388
|
-
* adjusting for a specified theme spacing.
|
|
389
|
-
*/
|
|
390
|
-
constructor(name, hostClass) {
|
|
391
|
-
this.name = name;
|
|
392
|
-
this.hostClass = hostClass;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
451
|
/**
|
|
397
452
|
* Defines properties of a SKY UX theme.
|
|
398
453
|
*/
|
|
@@ -429,10 +484,11 @@ class SkyThemeSettings {
|
|
|
429
484
|
* @param theme The theme configuration.
|
|
430
485
|
* @param mode The theme mode.
|
|
431
486
|
*/
|
|
432
|
-
constructor(theme, mode, spacing = SkyThemeSpacing.presets.standard) {
|
|
487
|
+
constructor(theme, mode, spacing = SkyThemeSpacing.presets.standard, brand) {
|
|
433
488
|
this.theme = theme;
|
|
434
489
|
this.mode = mode;
|
|
435
490
|
this.spacing = spacing;
|
|
491
|
+
this.brand = brand;
|
|
436
492
|
}
|
|
437
493
|
}
|
|
438
494
|
|
|
@@ -466,10 +522,10 @@ class SkyThemeDirective {
|
|
|
466
522
|
ngOnDestroy() {
|
|
467
523
|
this.#themeSvc.destroy();
|
|
468
524
|
}
|
|
469
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
470
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.
|
|
525
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SkyThemeService }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
526
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.1", type: SkyThemeDirective, isStandalone: false, selector: "[skyTheme]", inputs: { skyTheme: "skyTheme" }, providers: [SkyThemeService], ngImport: i0 }); }
|
|
471
527
|
}
|
|
472
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
528
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeDirective, decorators: [{
|
|
473
529
|
type: Directive,
|
|
474
530
|
args: [{
|
|
475
531
|
selector: '[skyTheme]',
|
|
@@ -481,13 +537,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
481
537
|
}] } });
|
|
482
538
|
|
|
483
539
|
class SkyThemeModule {
|
|
484
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
485
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
540
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
541
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeModule, declarations: [SkyThemeClassDirective,
|
|
486
542
|
SkyThemeDirective,
|
|
487
543
|
SkyThemeIfDirective], exports: [SkyThemeClassDirective, SkyThemeDirective, SkyThemeIfDirective] }); }
|
|
488
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
544
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeModule }); }
|
|
489
545
|
}
|
|
490
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
546
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeModule, decorators: [{
|
|
491
547
|
type: NgModule,
|
|
492
548
|
args: [{
|
|
493
549
|
declarations: [
|
|
@@ -499,6 +555,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
499
555
|
}]
|
|
500
556
|
}] });
|
|
501
557
|
|
|
558
|
+
/**
|
|
559
|
+
* @internal
|
|
560
|
+
* Defines properties of SKY UX theme branding.
|
|
561
|
+
*/
|
|
562
|
+
class SkyThemeBrand {
|
|
563
|
+
get hostClass() {
|
|
564
|
+
return this.#hostClass || `sky-theme-brand-${this.name}`;
|
|
565
|
+
}
|
|
566
|
+
set hostClass(value) {
|
|
567
|
+
this.#hostClass = value;
|
|
568
|
+
}
|
|
569
|
+
#hostClass;
|
|
570
|
+
/**
|
|
571
|
+
* Creates a new theme brand.
|
|
572
|
+
* @param name The name of the theme brand.
|
|
573
|
+
* @param hostClass The class on the host element which child components should reference when
|
|
574
|
+
* adjusting for a specified theme brand. This defaults to `sky-theme-brand-<name>
|
|
575
|
+
*/
|
|
576
|
+
constructor(name, version, hostClass) {
|
|
577
|
+
this.name = name;
|
|
578
|
+
this.version = version;
|
|
579
|
+
this.hostClass = hostClass;
|
|
580
|
+
if (!/\d+\.\d+\.\d+(?:-(?:alpha|beta|rc)\.\d)*$/.test(version)) {
|
|
581
|
+
throw new Error(`Invalid version format "${version}" for theme brand "${name}".`);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
502
586
|
class SkyThemeComponentClassDirective {
|
|
503
587
|
#changeDetector;
|
|
504
588
|
#themeService;
|
|
@@ -513,10 +597,10 @@ class SkyThemeComponentClassDirective {
|
|
|
513
597
|
this.#changeDetector.markForCheck();
|
|
514
598
|
});
|
|
515
599
|
}
|
|
516
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
517
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.
|
|
600
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeComponentClassDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
601
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.1", type: SkyThemeComponentClassDirective, isStandalone: true, selector: "[skyThemeClass]", host: { properties: { "class": "this.theme" } }, ngImport: i0 }); }
|
|
518
602
|
}
|
|
519
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
603
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyThemeComponentClassDirective, decorators: [{
|
|
520
604
|
type: Directive,
|
|
521
605
|
args: [{
|
|
522
606
|
selector: '[skyThemeClass]',
|
|
@@ -537,7 +621,10 @@ class SkyAppViewportService {
|
|
|
537
621
|
#reserveItems;
|
|
538
622
|
#conditionallyReserveItems;
|
|
539
623
|
#document;
|
|
624
|
+
#ngZone;
|
|
625
|
+
// Observe elements crossing the browser's viewport boundaries.
|
|
540
626
|
#intersectionObserver;
|
|
627
|
+
#reservedSpaces;
|
|
541
628
|
constructor() {
|
|
542
629
|
/**
|
|
543
630
|
* Updated when the viewport becomes visible. While the page is rendered, the
|
|
@@ -552,18 +639,15 @@ class SkyAppViewportService {
|
|
|
552
639
|
this.#reserveItems = new Map();
|
|
553
640
|
this.#conditionallyReserveItems = new Map();
|
|
554
641
|
this.#document = inject(DOCUMENT);
|
|
555
|
-
this.#
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
}
|
|
564
|
-
root: this.#document,
|
|
565
|
-
threshold: Array.from({ length: 11 }, (_, i) => i / 10),
|
|
566
|
-
});
|
|
642
|
+
this.#ngZone = inject(NgZone);
|
|
643
|
+
// Observe elements crossing the browser's viewport boundaries.
|
|
644
|
+
this.#intersectionObserver = this.#ngZone.runOutsideAngular(() => new IntersectionObserver(() => this.#ngZone.run(() => this.#updateViewportArea()), { threshold: Array.from({ length: 101 }, (_, i) => i / 100) }));
|
|
645
|
+
this.#reservedSpaces = {
|
|
646
|
+
bottom: 0,
|
|
647
|
+
left: 0,
|
|
648
|
+
right: 0,
|
|
649
|
+
top: 0,
|
|
650
|
+
};
|
|
567
651
|
const onScroll = () => {
|
|
568
652
|
if (this.#conditionallyReserveItems.size > 0) {
|
|
569
653
|
this.#updateViewportArea();
|
|
@@ -571,6 +655,10 @@ class SkyAppViewportService {
|
|
|
571
655
|
};
|
|
572
656
|
this.#document.addEventListener('scroll', onScroll);
|
|
573
657
|
inject(DestroyRef).onDestroy(() => {
|
|
658
|
+
/* istanbul ignore next */
|
|
659
|
+
if (this.#updateRequest !== undefined) {
|
|
660
|
+
cancelAnimationFrame(this.#updateRequest);
|
|
661
|
+
}
|
|
574
662
|
this.#intersectionObserver.disconnect();
|
|
575
663
|
this.#document.removeEventListener('scroll', onScroll);
|
|
576
664
|
});
|
|
@@ -582,8 +670,7 @@ class SkyAppViewportService {
|
|
|
582
670
|
reserveSpace(args) {
|
|
583
671
|
const item = {
|
|
584
672
|
...args,
|
|
585
|
-
active:
|
|
586
|
-
this.#isElementVisible(args.reserveForElement),
|
|
673
|
+
active: this.#isElementVisible({ ...args, active: false }),
|
|
587
674
|
};
|
|
588
675
|
this.#reserveItems.set(args.id, item);
|
|
589
676
|
this.#watchVisibility(item);
|
|
@@ -604,23 +691,24 @@ class SkyAppViewportService {
|
|
|
604
691
|
}
|
|
605
692
|
#updateViewportArea() {
|
|
606
693
|
this.#updateRequest ??= requestAnimationFrame(() => {
|
|
694
|
+
this.#updateRequest = undefined;
|
|
607
695
|
const reservedSpaces = {
|
|
608
696
|
bottom: 0,
|
|
609
697
|
left: 0,
|
|
610
698
|
right: 0,
|
|
611
699
|
top: 0,
|
|
612
700
|
};
|
|
613
|
-
for (const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
reservedSpaces[position] += size;
|
|
701
|
+
for (const args of this.#reserveItems.values()) {
|
|
702
|
+
args.active = this.#isElementVisible(args, reservedSpaces);
|
|
703
|
+
if (args.active) {
|
|
704
|
+
reservedSpaces[args.position] += args.size;
|
|
617
705
|
}
|
|
618
706
|
}
|
|
707
|
+
this.#reservedSpaces = reservedSpaces;
|
|
619
708
|
const documentElementStyle = this.#document.documentElement.style;
|
|
620
709
|
for (const [position, size] of Object.entries(reservedSpaces)) {
|
|
621
710
|
documentElementStyle.setProperty(`--sky-viewport-${position}`, size + 'px');
|
|
622
711
|
}
|
|
623
|
-
this.#updateRequest = undefined;
|
|
624
712
|
});
|
|
625
713
|
}
|
|
626
714
|
#watchVisibility(item) {
|
|
@@ -629,22 +717,50 @@ class SkyAppViewportService {
|
|
|
629
717
|
this.#intersectionObserver.observe(item.reserveForElement);
|
|
630
718
|
}
|
|
631
719
|
}
|
|
632
|
-
#isElementVisible(
|
|
633
|
-
|
|
634
|
-
|
|
720
|
+
#isElementVisible(args, reservedSpaces = this
|
|
721
|
+
.#reservedSpaces) {
|
|
722
|
+
if (!args.reserveForElement) {
|
|
723
|
+
return true;
|
|
724
|
+
}
|
|
725
|
+
const rect = args.reserveForElement.getBoundingClientRect();
|
|
726
|
+
if (!rect || !rect.height || !rect.width) {
|
|
727
|
+
return false;
|
|
728
|
+
}
|
|
729
|
+
const midpoint = {
|
|
730
|
+
x: rect.x + Math.floor(rect.width / 2),
|
|
731
|
+
y: rect.y + Math.floor(rect.height / 2),
|
|
732
|
+
};
|
|
733
|
+
if (
|
|
635
734
|
// Vertically in view
|
|
636
|
-
|
|
637
|
-
|
|
735
|
+
midpoint.y <= window.innerHeight &&
|
|
736
|
+
midpoint.y >= 0 &&
|
|
638
737
|
// Horizontally in view
|
|
639
|
-
|
|
640
|
-
|
|
738
|
+
midpoint.x <= window.innerWidth &&
|
|
739
|
+
midpoint.x >= 0) {
|
|
641
740
|
// Element is not hidden by another element
|
|
642
|
-
|
|
741
|
+
if (args.reserveForElement.contains(this.#document.elementFromPoint(midpoint.x, midpoint.y))) {
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
// Check if the item's midpoint is visible based on current reserved spaces.
|
|
745
|
+
// Assumes reserved spaces are intended to be additive and not overlapping.
|
|
746
|
+
const threshold = reservedSpaces[args.position];
|
|
747
|
+
switch (args.position) {
|
|
748
|
+
case 'top':
|
|
749
|
+
return midpoint.y >= threshold;
|
|
750
|
+
case 'right':
|
|
751
|
+
return midpoint.x <= window.innerWidth - threshold;
|
|
752
|
+
case 'bottom':
|
|
753
|
+
return midpoint.y <= window.innerHeight - threshold;
|
|
754
|
+
case 'left':
|
|
755
|
+
return midpoint.x >= threshold;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return false;
|
|
643
759
|
}
|
|
644
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
645
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
760
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyAppViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
761
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyAppViewportService, providedIn: 'root' }); }
|
|
646
762
|
}
|
|
647
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
763
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SkyAppViewportService, decorators: [{
|
|
648
764
|
type: Injectable,
|
|
649
765
|
args: [{
|
|
650
766
|
providedIn: 'root',
|
|
@@ -669,5 +785,5 @@ function provideInitialTheme(name = 'default', options) {
|
|
|
669
785
|
* Generated bundle index. Do not edit.
|
|
670
786
|
*/
|
|
671
787
|
|
|
672
|
-
export { SkyAppStyleLoader, SkyAppViewportService, SkyTheme, SkyThemeComponentClassDirective, SkyThemeIconManifestService, SkyThemeMode, SkyThemeModule, SkyThemeService, SkyThemeSettings, SkyThemeSpacing, provideInitialTheme, SkyThemeDirective as λ1, SkyThemeClassDirective as λ2, SkyThemeIfDirective as λ3 };
|
|
788
|
+
export { SkyAppStyleLoader, SkyAppViewportService, SkyTheme, SkyThemeBrand, SkyThemeComponentClassDirective, SkyThemeIconManifestService, SkyThemeMode, SkyThemeModule, SkyThemeService, SkyThemeSettings, SkyThemeSpacing, provideInitialTheme, SkyThemeDirective as λ1, SkyThemeClassDirective as λ2, SkyThemeIfDirective as λ3 };
|
|
673
789
|
//# sourceMappingURL=skyux-theme.mjs.map
|