@skyux/theme 13.0.0-alpha.0 → 13.0.0-alpha.1

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.
@@ -237,12 +237,17 @@ class SkyThemeBrand {
237
237
  /**
238
238
  * Creates a new theme brand.
239
239
  * @param name The name of the theme brand.
240
+ * @param version The version of the theme brand.
240
241
  * @param hostClass The class on the host element which child components should reference when
241
- * adjusting for a specified theme brand. This defaults to `sky-theme-brand-<name>
242
+ * adjusting for a specified theme brand. This defaults to `sky-theme-brand-<name>`
243
+ * @param styleUrl The URL of the stylesheet to load for this brand
244
+ * @param sriHash The subresource integrity hash for the stylesheet
242
245
  */
243
- constructor(name, version, hostClass) {
246
+ constructor(name, version, hostClass, styleUrl, sriHash) {
244
247
  this.name = name;
245
248
  this.version = version;
249
+ this.styleUrl = styleUrl;
250
+ this.sriHash = sriHash;
246
251
  this.hostClass = hostClass;
247
252
  if (!/\d+\.\d+\.\d+(?:-(?:alpha|beta|rc)\.\d)*$/.test(version)) {
248
253
  throw new Error(`Invalid version format "${version}" for theme brand "${name}".`);
@@ -262,6 +267,13 @@ class SkyThemeBrand {
262
267
  if (this.hostClass !== defaultHostClass) {
263
268
  result.hostClass = this.hostClass;
264
269
  }
270
+ // Include styleUrl and sriHash if they are provided
271
+ if (this.styleUrl) {
272
+ result.styleUrl = this.styleUrl;
273
+ }
274
+ if (this.sriHash) {
275
+ result.sriHash = this.sriHash;
276
+ }
265
277
  return result;
266
278
  }
267
279
  /**
@@ -269,7 +281,7 @@ class SkyThemeBrand {
269
281
  * Deserializes a JSON object to a SkyThemeBrand instance.
270
282
  */
271
283
  static deserialize(data) {
272
- return new SkyThemeBrand(data.name, data.version, data.hostClass);
284
+ return new SkyThemeBrand(data.name, data.version, data.hostClass, data.styleUrl, data.sriHash);
273
285
  }
274
286
  #buildDefaultHostClassName() {
275
287
  return `sky-theme-brand-${this.name}`;
@@ -326,6 +338,7 @@ class SkyThemeSettings {
326
338
  }
327
339
  }
328
340
 
341
+ const BRAND_BLACKBAUD = 'blackbaud';
329
342
  function assertCurrentSettings(currentSettings) {
330
343
  if (!currentSettings) {
331
344
  throw new Error('Theme service is not initialized. Call init() first.');
@@ -346,6 +359,7 @@ class SkyThemeService {
346
359
  #hostEl;
347
360
  #renderer;
348
361
  #settings;
362
+ #registeredBrands = new Map();
349
363
  #_settingsObs;
350
364
  constructor() {
351
365
  this.#settings = new ReplaySubject(1);
@@ -357,10 +371,17 @@ class SkyThemeService {
357
371
  * @param hostEl The host element under which themed components are rendered.
358
372
  * @param renderer A Renderer2 instance for updating the host element with theme changes.
359
373
  * @param theme The initial theme.
374
+ * @param registeredBrands An initial set of brands to register. Additional brands can
375
+ * be registered later via the registerBrand() method.
360
376
  */
361
- init(hostEl, renderer, theme) {
377
+ init(hostEl, renderer, theme, registeredBrands) {
362
378
  this.#hostEl = hostEl;
363
379
  this.#renderer = renderer;
380
+ if (registeredBrands) {
381
+ for (const brand of registeredBrands) {
382
+ this.#registeredBrands.set(brand.name, brand);
383
+ }
384
+ }
364
385
  this.setTheme(theme);
365
386
  }
366
387
  /**
@@ -395,7 +416,7 @@ class SkyThemeService {
395
416
  setTheme(settingsOrTheme) {
396
417
  let settings;
397
418
  if (settingsOrTheme instanceof SkyThemeSettings) {
398
- settings = settingsOrTheme;
419
+ settings = this.#applyRegisteredBrand(settingsOrTheme);
399
420
  }
400
421
  else {
401
422
  const current = this.#current;
@@ -413,6 +434,22 @@ class SkyThemeService {
413
434
  });
414
435
  this.#current = settings;
415
436
  }
437
+ registerBrand(brand) {
438
+ this.#registeredBrands.set(brand.name, brand);
439
+ }
440
+ unregisterBrand(name) {
441
+ this.#registeredBrands.delete(name);
442
+ }
443
+ #applyRegisteredBrand(settings) {
444
+ const brandName = settings.brand?.name;
445
+ if (brandName) {
446
+ const registeredBrand = this.#registeredBrands.get(brandName);
447
+ if (registeredBrand) {
448
+ settings = new SkyThemeSettings(settings.theme, settings.mode, settings.spacing, registeredBrand);
449
+ }
450
+ }
451
+ return settings;
452
+ }
416
453
  #updateThemeProperty(property, value) {
417
454
  const current = this.#current;
418
455
  assertCurrentSettings(current);
@@ -454,14 +491,12 @@ class SkyThemeService {
454
491
  }
455
492
  }
456
493
  #updateBrandStylesheet(currentBrand, previousBrand) {
457
- if (currentBrand &&
458
- currentBrand.name !== 'blackbaud' &&
459
- previousBrand !== currentBrand) {
460
- this.#addBrandStylesheet(currentBrand);
461
- }
462
- else {
494
+ if (previousBrand && previousBrand.name !== BRAND_BLACKBAUD) {
463
495
  this.#removeBrandStylesheet();
464
496
  }
497
+ if (currentBrand && currentBrand.name !== BRAND_BLACKBAUD) {
498
+ this.#addBrandStylesheet(currentBrand);
499
+ }
465
500
  }
466
501
  #updateHostClass(prop, previousClass, currentClass, currentSetting, current, supportedProp) {
467
502
  if (previousClass) {
@@ -481,15 +516,19 @@ class SkyThemeService {
481
516
  }
482
517
  }
483
518
  #addBrandStylesheet(brand) {
484
- if (brand.name !== 'blackbaud') {
485
- const cssPath = `https://sky.blackbaudcdn.net/static/skyux-brand-${brand.name}/${brand.version}/assets/scss/${brand.name}.css`;
486
- // Create a link element via Angular's renderer to avoid SSR troubles
487
- this.#brandLinkElement = this.#getRenderer().createElement('link');
488
- // Add the style to the head section
489
- this.#getRenderer().appendChild(this.#hostEl, this.#brandLinkElement);
490
- // Set type of the link item and path to the css file
491
- this.#getRenderer().setProperty(this.#brandLinkElement, 'rel', 'stylesheet');
492
- this.#getRenderer().setProperty(this.#brandLinkElement, 'href', cssPath);
519
+ if (brand.name !== BRAND_BLACKBAUD) {
520
+ // Use styleUrl if provided, otherwise build the default URL
521
+ const styleUrl = brand.styleUrl ||
522
+ `https://sky.blackbaudcdn.net/static/skyux-brand-${brand.name}/${brand.version}/assets/scss/${brand.name}.css`;
523
+ const renderer = this.#getRenderer();
524
+ this.#brandLinkElement = renderer.createElement('link');
525
+ renderer.appendChild(this.#hostEl, this.#brandLinkElement);
526
+ renderer.setAttribute(this.#brandLinkElement, 'rel', 'stylesheet');
527
+ renderer.setAttribute(this.#brandLinkElement, 'href', styleUrl);
528
+ if (brand.sriHash) {
529
+ renderer.setAttribute(this.#brandLinkElement, 'integrity', brand.sriHash);
530
+ renderer.setAttribute(this.#brandLinkElement, 'crossorigin', 'anonymous');
531
+ }
493
532
  }
494
533
  }
495
534
  #removeBrandStylesheet() {