@momentum-design/components 0.140.0 → 0.141.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.
Files changed (30) hide show
  1. package/dist/browser/index.js +424 -424
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/brandvisual/brandvisual.component.d.ts +49 -1
  4. package/dist/components/brandvisual/brandvisual.component.js +154 -19
  5. package/dist/components/brandvisualprovider/brandvisualprovider.component.d.ts +97 -0
  6. package/dist/components/brandvisualprovider/brandvisualprovider.component.js +105 -0
  7. package/dist/components/brandvisualprovider/brandvisualprovider.constants.d.ts +7 -0
  8. package/dist/components/brandvisualprovider/brandvisualprovider.constants.js +10 -0
  9. package/dist/components/brandvisualprovider/brandvisualprovider.context.d.ts +12 -0
  10. package/dist/components/brandvisualprovider/brandvisualprovider.context.js +7 -0
  11. package/dist/components/brandvisualprovider/brandvisualprovider.types.d.ts +3 -0
  12. package/dist/components/brandvisualprovider/brandvisualprovider.types.js +1 -0
  13. package/dist/components/brandvisualprovider/index.d.ts +7 -0
  14. package/dist/components/brandvisualprovider/index.js +4 -0
  15. package/dist/components/icon/icon.component.js +3 -2
  16. package/dist/components/illustration/illustration.component.js +3 -2
  17. package/dist/custom-elements.json +252 -7
  18. package/dist/index.d.ts +2 -1
  19. package/dist/index.js +2 -1
  20. package/dist/react/brandvisualprovider/index.d.ts +24 -0
  21. package/dist/react/brandvisualprovider/index.js +17 -0
  22. package/dist/react/index.d.ts +1 -0
  23. package/dist/react/index.js +1 -0
  24. package/dist/utils/asset-fetch/index.d.ts +42 -0
  25. package/dist/utils/asset-fetch/index.js +101 -0
  26. package/package.json +1 -1
  27. package/dist/components/icon/icon.utils.d.ts +0 -32
  28. package/dist/components/icon/icon.utils.js +0 -91
  29. package/dist/components/illustration/illustration.utils.d.ts +0 -32
  30. package/dist/components/illustration/illustration.utils.js +0 -91
@@ -34,14 +34,62 @@ declare class Brandvisual extends Component {
34
34
  * This will only be set if the brandvisual is an image (png).
35
35
  */
36
36
  altText?: string;
37
+ private readonly brandVisualProviderContext;
38
+ private abortController?;
39
+ constructor();
40
+ /**
41
+ * Resolves the brandvisual, either over HTTP through a `BrandVisualProvider` or through a
42
+ * dynamic import of the lit template shipped in the `@momentum-design/brand-visuals` package.
43
+ *
44
+ * The dynamic import is the fallback for every case that is not a fully configured custom set:
45
+ * no provider at all, the momentum set, or a custom set that is missing a url or file extension.
46
+ * Keeping it reachable without a provider is what makes this backwards compatible - a bare
47
+ * `<mdc-brandvisual name="…">` behaves exactly as it did before the provider existed.
48
+ */
37
49
  private getBrandVisualData;
50
+ /**
51
+ * Fetches a vector brandvisual over HTTP and inlines it.
52
+ *
53
+ * This method uses abortController.signal to cancel the fetch request when the component is
54
+ * disconnected or updated. If the request is aborted after the fetch() call has been fulfilled
55
+ * but before the response body has been read, then attempting to read the response body will
56
+ * reject with an AbortError exception.
57
+ */
58
+ private fetchBrandVisual;
59
+ /**
60
+ * Points an `img` at the raster brandvisual and resolves once the browser has loaded it.
61
+ *
62
+ * There is nothing to fetch here - assigning `src` starts the load even while the element is
63
+ * detached - but we still wait for it so that `load` and `error` keep meaning the same thing
64
+ * they do on the other two branches.
65
+ */
66
+ private loadBrandVisualImage;
67
+ /**
68
+ * Parse the fetched brandvisual string to an html element and set the attributes the
69
+ * packaged lit templates would otherwise carry.
70
+ *
71
+ * @param brandVisualData - The brandvisual string to be parsed
72
+ * @returns brandVisualElement
73
+ */
74
+ private prepareBrandVisualElement;
38
75
  updated(changedProperties: Map<string, any>): void;
76
+ disconnectedCallback(): void;
77
+ /**
78
+ * Labels the brandvisual with the alt text, if it has anything to label.
79
+ *
80
+ * The dynamic import hands back a lit `TemplateResult`, whose markup has to be parsed before an
81
+ * `img` can be found in it, while both provider branches already produce an `Element` - so the
82
+ * two need different treatment. Only raster visuals have an `img` to label; vector ones are
83
+ * `aria-hidden` by design and are returned untouched.
84
+ */
85
+ private applyAltText;
39
86
  private injectTemplateAttributes;
40
87
  private injectHtmlAttributes;
41
88
  /**
42
89
  * Sets the brandVisualData state to the fetched brandvisual.
43
90
  * Dispatches a 'load' event on the component once the brandvisual has been successfully loaded.
44
- * @param brandVisualHtml - The brandvisual html element which has been fetched from the brandvisual provider.
91
+ * @param brandVisualHtml - The brandvisual which has been resolved, either as the lit template
92
+ * from the dynamic import or as an element built from the provider url.
45
93
  */
46
94
  private handleBrandVisualLoadedSuccess;
47
95
  /**
@@ -10,6 +10,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  import { html } from 'lit';
11
11
  import { property, state } from 'lit/decorators.js';
12
12
  import { Component } from '../../models';
13
+ import providerUtils from '../../utils/provider';
14
+ import { assetFetch } from '../../utils/asset-fetch';
15
+ import BrandVisualProvider from '../brandvisualprovider/brandvisualprovider.component';
13
16
  import styles from './brandvisual.styles';
14
17
  /**
15
18
  * @tagname mdc-brandvisual
@@ -21,61 +24,189 @@ import styles from './brandvisual.styles';
21
24
  * @csspart brandvisualImage - Set styles for the brandvisual image container
22
25
  */
23
26
  class Brandvisual extends Component {
27
+ constructor() {
28
+ super();
29
+ this.brandVisualProviderContext = providerUtils.consume({
30
+ host: this,
31
+ context: BrandVisualProvider.Context,
32
+ });
33
+ this.abortController = new AbortController(); // Initialize AbortController
34
+ }
35
+ /**
36
+ * Resolves the brandvisual, either over HTTP through a `BrandVisualProvider` or through a
37
+ * dynamic import of the lit template shipped in the `@momentum-design/brand-visuals` package.
38
+ *
39
+ * The dynamic import is the fallback for every case that is not a fully configured custom set:
40
+ * no provider at all, the momentum set, or a custom set that is missing a url or file extension.
41
+ * Keeping it reachable without a provider is what makes this backwards compatible - a bare
42
+ * `<mdc-brandvisual name="…">` behaves exactly as it did before the provider existed.
43
+ */
24
44
  async getBrandVisualData() {
45
+ if (!this.name) {
46
+ const nameError = new Error('No brandvisual name provided.');
47
+ this.handleBrandVisualLoadedFailure(nameError);
48
+ return Promise.reject(nameError);
49
+ }
50
+ const providerContext = this.brandVisualProviderContext.value;
51
+ if ((providerContext === null || providerContext === void 0 ? void 0 : providerContext.brandVisualSet) === 'custom-brand-visuals') {
52
+ const { url, fileExtension, cacheName, cacheStrategy } = providerContext;
53
+ if (url && fileExtension) {
54
+ // raster visuals are handed to the browser as an <img src>, vector ones are fetched
55
+ // and inlined so they can be styled through ::part(brandvisual)
56
+ return fileExtension === 'png'
57
+ ? this.loadBrandVisualImage(url, fileExtension)
58
+ : this.fetchBrandVisual({ url, fileExtension, cacheName, cacheStrategy });
59
+ }
60
+ }
61
+ // dynamic import of the lit template from the momentum brand-visuals package
62
+ return import(`@momentum-design/brand-visuals/dist/ts/${this.name}.ts`)
63
+ .then(module => {
64
+ this.handleBrandVisualLoadedSuccess(module.default());
65
+ })
66
+ .catch(error => {
67
+ this.handleBrandVisualLoadedFailure(error);
68
+ });
69
+ }
70
+ /**
71
+ * Fetches a vector brandvisual over HTTP and inlines it.
72
+ *
73
+ * This method uses abortController.signal to cancel the fetch request when the component is
74
+ * disconnected or updated. If the request is aborted after the fetch() call has been fulfilled
75
+ * but before the response body has been read, then attempting to read the response body will
76
+ * reject with an AbortError exception.
77
+ */
78
+ async fetchBrandVisual({ url, fileExtension, cacheName, cacheStrategy, }) {
79
+ // function to abort the fetch request and create a new signal
80
+ // (directly passing the abortcontroller to the fetch request per reference
81
+ // will not work due to JS call-by-sharing behavior)
82
+ const renewSignal = () => {
83
+ var _a;
84
+ (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
85
+ this.abortController = new AbortController();
86
+ return this.abortController.signal;
87
+ };
88
+ return assetFetch({
89
+ url,
90
+ name: this.name,
91
+ fileExtension,
92
+ cacheName,
93
+ cacheStrategy,
94
+ renewSignal,
95
+ assetType: 'brand visual',
96
+ })
97
+ .then(brandVisualData => {
98
+ this.handleBrandVisualLoadedSuccess(this.prepareBrandVisualElement(brandVisualData));
99
+ })
100
+ .catch(error => {
101
+ this.handleBrandVisualLoadedFailure(error);
102
+ });
103
+ }
104
+ /**
105
+ * Points an `img` at the raster brandvisual and resolves once the browser has loaded it.
106
+ *
107
+ * There is nothing to fetch here - assigning `src` starts the load even while the element is
108
+ * detached - but we still wait for it so that `load` and `error` keep meaning the same thing
109
+ * they do on the other two branches.
110
+ */
111
+ async loadBrandVisualImage(url, fileExtension) {
112
+ const image = document.createElement('img');
113
+ image.setAttribute('part', 'brandvisualImage');
114
+ image.setAttribute('data-name', this.name);
115
+ return new Promise(resolve => {
116
+ image.onload = () => {
117
+ this.handleBrandVisualLoadedSuccess(image);
118
+ resolve();
119
+ };
120
+ image.onerror = () => {
121
+ this.handleBrandVisualLoadedFailure(new Error('There was a problem while fetching the brand visual!'));
122
+ resolve();
123
+ };
124
+ image.src = `${url}/${this.name}.${fileExtension}`;
125
+ });
126
+ }
127
+ /**
128
+ * Parse the fetched brandvisual string to an html element and set the attributes the
129
+ * packaged lit templates would otherwise carry.
130
+ *
131
+ * @param brandVisualData - The brandvisual string to be parsed
132
+ * @returns brandVisualElement
133
+ */
134
+ prepareBrandVisualElement(brandVisualData) {
135
+ const brandVisualElement = new DOMParser().parseFromString(brandVisualData, 'text/html').body.children[0];
25
136
  if (this.name) {
26
- // dynamic import of the lit template from the momentum brand-visuals package
27
- return import(`@momentum-design/brand-visuals/dist/ts/${this.name}.ts`)
28
- .then(module => {
29
- this.handleBrandVisualLoadedSuccess(module.default());
30
- })
31
- .catch(error => {
32
- this.handleBrandVisualLoadedFailure(error);
33
- });
137
+ brandVisualElement.setAttribute('data-name', this.name);
34
138
  }
35
- const nameError = new Error('No brandvisual name provided.');
36
- this.handleBrandVisualLoadedFailure(nameError);
37
- return Promise.reject(nameError);
139
+ brandVisualElement.setAttribute('part', 'brandvisual');
140
+ // set aria-hidden=true for SVG to avoid screen readers
141
+ brandVisualElement.setAttribute('aria-hidden', 'true');
142
+ return brandVisualElement;
38
143
  }
39
144
  updated(changedProperties) {
40
145
  super.updated(changedProperties);
41
146
  if (changedProperties.has('name')) {
42
147
  // import brandVisual data if name changes:
43
148
  this.getBrandVisualData().catch(err => {
44
- if (this.onerror) {
149
+ if (err.name !== 'AbortError' && this.onerror) {
45
150
  this.onerror(err);
46
151
  }
47
152
  });
48
153
  }
49
154
  if (changedProperties.has('altText')) {
50
155
  if (this.brandVisualData) {
51
- this.brandVisualData = this.injectHtmlAttributes(this.brandVisualData, { alt: this.altText });
156
+ this.brandVisualData = this.applyAltText(this.brandVisualData);
52
157
  }
53
158
  }
54
159
  }
160
+ disconnectedCallback() {
161
+ var _a;
162
+ super.disconnectedCallback();
163
+ // abort the fetch request when the component is disconnected
164
+ (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
165
+ this.abortController = undefined; // reset the abort controller
166
+ }
167
+ /**
168
+ * Labels the brandvisual with the alt text, if it has anything to label.
169
+ *
170
+ * The dynamic import hands back a lit `TemplateResult`, whose markup has to be parsed before an
171
+ * `img` can be found in it, while both provider branches already produce an `Element` - so the
172
+ * two need different treatment. Only raster visuals have an `img` to label; vector ones are
173
+ * `aria-hidden` by design and are returned untouched.
174
+ */
175
+ applyAltText(brandVisual) {
176
+ if (brandVisual instanceof Element) {
177
+ return brandVisual.tagName === 'IMG' ? this.injectHtmlAttributes(brandVisual, { alt: this.altText }) : brandVisual;
178
+ }
179
+ return this.injectTemplateAttributes(brandVisual, 'img', { alt: this.altText });
180
+ }
55
181
  injectTemplateAttributes(litTemplate, tag, props) {
56
182
  const parser = new DOMParser();
57
183
  const doc = parser.parseFromString(litTemplate.strings[0], 'text/html');
58
184
  const element = doc.querySelector(tag);
59
185
  if (element) {
60
- Object.entries(props).forEach(([key, value]) => {
61
- element.setAttribute(key, value);
62
- });
186
+ this.injectHtmlAttributes(element, props);
63
187
  }
64
188
  return element || litTemplate;
65
189
  }
66
190
  injectHtmlAttributes(html, props) {
67
191
  Object.entries(props).forEach(([key, value]) => {
68
- html.setAttribute(key, value);
192
+ // an unset alt-text must not end up rendered as alt="undefined"
193
+ if (value === undefined) {
194
+ html.removeAttribute(key);
195
+ }
196
+ else {
197
+ html.setAttribute(key, value);
198
+ }
69
199
  });
70
200
  return html;
71
201
  }
72
202
  /**
73
203
  * Sets the brandVisualData state to the fetched brandvisual.
74
204
  * Dispatches a 'load' event on the component once the brandvisual has been successfully loaded.
75
- * @param brandVisualHtml - The brandvisual html element which has been fetched from the brandvisual provider.
205
+ * @param brandVisualHtml - The brandvisual which has been resolved, either as the lit template
206
+ * from the dynamic import or as an element built from the provider url.
76
207
  */
77
208
  handleBrandVisualLoadedSuccess(brandVisualHtml) {
78
- this.brandVisualData = this.injectTemplateAttributes(brandVisualHtml, 'img', { alt: this.altText });
209
+ this.brandVisualData = this.applyAltText(brandVisualHtml);
79
210
  // when brandvisual is imported successfully, trigger brandvisual load event.
80
211
  const loadEvent = new Event('load', {
81
212
  bubbles: true,
@@ -113,4 +244,8 @@ __decorate([
113
244
  property({ type: String, reflect: true, attribute: 'alt-text' }),
114
245
  __metadata("design:type", String)
115
246
  ], Brandvisual.prototype, "altText", void 0);
247
+ __decorate([
248
+ state(),
249
+ __metadata("design:type", AbortController)
250
+ ], Brandvisual.prototype, "abortController", void 0);
116
251
  export default Brandvisual;
@@ -0,0 +1,97 @@
1
+ import { Provider } from '../../models';
2
+ import BrandVisualProviderContext from './brandvisualprovider.context';
3
+ import type { BrandVisualSet, CacheStrategy } from './brandvisualprovider.types';
4
+ /**
5
+ * The brandvisualprovider is the context provider for `mdc-brandvisual`. It lets an application configure where brand visuals come from and how they are cached in one place, so every nested brand visual stays consistent without repeating that setup at each usage.
6
+ *
7
+ * Without a provider, `mdc-brandvisual` resolves its asset through a dynamic import of the lit template shipped in `@momentum-design/brand-visuals`. That import is not statically analysable, so bundlers have to account for every asset in the package. Pointing the provider at a URL replaces that import with an HTTP fetch, which lets an application serve the brand visual set itself and keep it out of the bundle entirely.
8
+ *
9
+ * **When to use**
10
+ *
11
+ * - Use `mdc-brandvisualprovider` to configure the brand visual source once for every nested `mdc-brandvisual` in a subtree.
12
+ * - Use `mdc-brandvisualprovider` with `brand-visual-set="custom-brand-visuals"` when brand visuals should be served over HTTP rather than bundled — for example in a host framework that cannot afford to bundle the full asset set.
13
+ * - Use `mdc-brandvisualprovider` when brand visuals should be cached across re-renders or navigations to avoid repeated network fetches.
14
+ *
15
+ * **When not to use**
16
+ *
17
+ * - Do not expect one provider to cover every brand visual when fetching over HTTP. The set is split across an `svg` and a `png` folder and a provider points at one of them, so a page using artwork from both needs one provider for each — see **Content guidance** below. Outside that case, prefer a single provider near the root and nest only when a subtree genuinely needs a different source.
18
+ * - Do not reach for `mdc-brandvisualprovider` to render a logo — it has no visible UI. Use `mdc-brandvisual` for the visual itself.
19
+ * - Do not add a provider purely to keep the existing behaviour. `mdc-brandvisual` works without one.
20
+ *
21
+ * @tagname mdc-brandvisualprovider
22
+ *
23
+ * @slot - children
24
+ */
25
+ declare class BrandVisualProvider extends Provider<BrandVisualProviderContext> {
26
+ constructor();
27
+ /**
28
+ * Context object of the BrandVisualProviderContext, to be consumed by child components
29
+ */
30
+ static get Context(): {
31
+ __context__: BrandVisualProviderContext;
32
+ };
33
+ /**
34
+ * Brand visual set to be used
35
+ *
36
+ * If `momentum-brand-visuals` is selected, the brand visuals will be fetched from the
37
+ * Momentum Design System brand visual set per a dynamic JS Import (no need to provide a URL).
38
+ * This requires the consumer to have the `@momentum-design/brand-visuals` package installed and the
39
+ * build tooling needs to support dynamic imports.
40
+ *
41
+ * If `custom-brand-visuals` is selected, the brand visuals will be fetched from the provided URL.
42
+ * This requires the consumer to provide a URL from which the brand visuals will be fetched and
43
+ * the consumer needs to make sure to bundle the brand visuals in the application.
44
+ *
45
+ * @default momentum-brand-visuals
46
+ */
47
+ brandVisualSet?: BrandVisualSet;
48
+ /**
49
+ * Url of where brand visuals will be fetched from
50
+ * (if Brand visual set is `custom-brand-visuals`, this will be the base url)
51
+ */
52
+ url?: string;
53
+ /**
54
+ * File extension of brand visuals
55
+ * (if Brand visual set is `custom-brand-visuals`, this will be the file extension for brand visuals)
56
+ *
57
+ * `svg` visuals are fetched and inlined, `png` visuals are set as the `src` of an `img` element.
58
+ * Note that the two sets are not interchangeable: the device visuals only ship as `png`,
59
+ * every other visual only ships as `svg`.
60
+ *
61
+ * @default svg
62
+ */
63
+ fileExtension?: string;
64
+ /**
65
+ * Brand visuals Cache Strategy to use
66
+ *
67
+ * **Can only be used if Brand visual set is `custom-brand-visuals` and the file extension is `svg`**
68
+ * (`png` visuals are loaded by the browser through an `img` element and are subject to the
69
+ * regular HTTP cache instead).
70
+ *
71
+ * Choose `in-memory-cache` to cache brand visuals in a JS cache (in-memory cache).
72
+ * Choose `web-cache-api` to cache brand visuals using the Web Cache API.
73
+ *
74
+ * NOTE: `cache-name` must be provided if `cache-strategy` is provided.
75
+ *
76
+ * If not provided or invalid value provided, the brand visuals will not be cached.
77
+ * @default undefined
78
+ */
79
+ cacheStrategy?: CacheStrategy;
80
+ /**
81
+ * Brand visuals Cache Name to use (cache strategy must be provided)
82
+ *
83
+ * If provided, Brand visuals inside the provider will be cached in the
84
+ * cache (determined by `cache-strategy`) with the provided name.
85
+ *
86
+ * Brand visuals cache name must be unique, independent from other asset caches.
87
+ *
88
+ * NOTE: `cache-name` requires `cache-strategy` to be set.
89
+ *
90
+ * If not provided, the brand visuals will not be cached.
91
+ * @default undefined
92
+ */
93
+ cacheName?: string;
94
+ private updateValuesInContext;
95
+ protected updateContext(): void;
96
+ }
97
+ export default BrandVisualProvider;
@@ -0,0 +1,105 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { property } from 'lit/decorators.js';
11
+ import { Provider } from '../../models';
12
+ import BrandVisualProviderContext from './brandvisualprovider.context';
13
+ import { ALLOWED_FILE_EXTENSIONS, DEFAULTS } from './brandvisualprovider.constants';
14
+ /**
15
+ * @tagname mdc-brandvisualprovider
16
+ *
17
+ * @slot - children
18
+ */
19
+ class BrandVisualProvider extends Provider {
20
+ constructor() {
21
+ // initialise the context by running the Provider constructor:
22
+ super({
23
+ context: BrandVisualProviderContext.context,
24
+ initialValue: new BrandVisualProviderContext(),
25
+ });
26
+ /**
27
+ * Brand visual set to be used
28
+ *
29
+ * If `momentum-brand-visuals` is selected, the brand visuals will be fetched from the
30
+ * Momentum Design System brand visual set per a dynamic JS Import (no need to provide a URL).
31
+ * This requires the consumer to have the `@momentum-design/brand-visuals` package installed and the
32
+ * build tooling needs to support dynamic imports.
33
+ *
34
+ * If `custom-brand-visuals` is selected, the brand visuals will be fetched from the provided URL.
35
+ * This requires the consumer to provide a URL from which the brand visuals will be fetched and
36
+ * the consumer needs to make sure to bundle the brand visuals in the application.
37
+ *
38
+ * @default momentum-brand-visuals
39
+ */
40
+ this.brandVisualSet = DEFAULTS.BRAND_VISUAL_SET;
41
+ /**
42
+ * File extension of brand visuals
43
+ * (if Brand visual set is `custom-brand-visuals`, this will be the file extension for brand visuals)
44
+ *
45
+ * `svg` visuals are fetched and inlined, `png` visuals are set as the `src` of an `img` element.
46
+ * Note that the two sets are not interchangeable: the device visuals only ship as `png`,
47
+ * every other visual only ships as `svg`.
48
+ *
49
+ * @default svg
50
+ */
51
+ this.fileExtension = DEFAULTS.FILE_EXTENSION;
52
+ }
53
+ /**
54
+ * Context object of the BrandVisualProviderContext, to be consumed by child components
55
+ */
56
+ static get Context() {
57
+ return BrandVisualProviderContext.context;
58
+ }
59
+ updateValuesInContext() {
60
+ // only update fileExtension on context if its an allowed fileExtension
61
+ if (this.fileExtension && ALLOWED_FILE_EXTENSIONS.includes(this.fileExtension)) {
62
+ this.context.value.fileExtension = this.fileExtension;
63
+ }
64
+ else {
65
+ // Ensure both fileExtension and context are updated to the default if its not an allowed fileExtension
66
+ this.fileExtension = DEFAULTS.FILE_EXTENSION;
67
+ this.context.value.fileExtension = DEFAULTS.FILE_EXTENSION;
68
+ }
69
+ this.context.value.brandVisualSet = this.brandVisualSet;
70
+ this.context.value.url = this.url;
71
+ this.context.value.cacheName = this.cacheName;
72
+ this.context.value.cacheStrategy = this.cacheStrategy;
73
+ }
74
+ updateContext() {
75
+ if (this.context.value.fileExtension !== this.fileExtension ||
76
+ this.context.value.brandVisualSet !== this.brandVisualSet ||
77
+ this.context.value.url !== this.url ||
78
+ this.context.value.cacheName !== this.cacheName ||
79
+ this.context.value.cacheStrategy !== this.cacheStrategy) {
80
+ this.updateValuesInContext();
81
+ this.context.updateObservers();
82
+ }
83
+ }
84
+ }
85
+ __decorate([
86
+ property({ type: String, attribute: 'brand-visual-set', reflect: true }),
87
+ __metadata("design:type", String)
88
+ ], BrandVisualProvider.prototype, "brandVisualSet", void 0);
89
+ __decorate([
90
+ property({ type: String }),
91
+ __metadata("design:type", String)
92
+ ], BrandVisualProvider.prototype, "url", void 0);
93
+ __decorate([
94
+ property({ type: String, attribute: 'file-extension', reflect: true }),
95
+ __metadata("design:type", String)
96
+ ], BrandVisualProvider.prototype, "fileExtension", void 0);
97
+ __decorate([
98
+ property({ type: String, attribute: 'cache-strategy' }),
99
+ __metadata("design:type", String)
100
+ ], BrandVisualProvider.prototype, "cacheStrategy", void 0);
101
+ __decorate([
102
+ property({ type: String, attribute: 'cache-name' }),
103
+ __metadata("design:type", String)
104
+ ], BrandVisualProvider.prototype, "cacheName", void 0);
105
+ export default BrandVisualProvider;
@@ -0,0 +1,7 @@
1
+ declare const TAG_NAME: "mdc-brandvisualprovider";
2
+ declare const ALLOWED_FILE_EXTENSIONS: string[];
3
+ declare const DEFAULTS: {
4
+ readonly FILE_EXTENSION: "svg";
5
+ readonly BRAND_VISUAL_SET: "momentum-brand-visuals";
6
+ };
7
+ export { TAG_NAME, DEFAULTS, ALLOWED_FILE_EXTENSIONS };
@@ -0,0 +1,10 @@
1
+ import utils from '../../utils/tag-name';
2
+ const TAG_NAME = utils.constructTagName('brandvisualprovider');
3
+ // brand visuals ship as vectors (`dist/svg`) and, for the device photography,
4
+ // as raster images (`dist/png`) — so both are valid custom set extensions.
5
+ const ALLOWED_FILE_EXTENSIONS = ['svg', 'png'];
6
+ const DEFAULTS = {
7
+ FILE_EXTENSION: 'svg',
8
+ BRAND_VISUAL_SET: 'momentum-brand-visuals',
9
+ };
10
+ export { TAG_NAME, DEFAULTS, ALLOWED_FILE_EXTENSIONS };
@@ -0,0 +1,12 @@
1
+ import type { BrandVisualSet, CacheStrategy } from './brandvisualprovider.types';
2
+ declare class BrandVisualProviderContext {
3
+ brandVisualSet?: BrandVisualSet;
4
+ fileExtension?: string;
5
+ url?: string;
6
+ cacheName?: string;
7
+ cacheStrategy?: CacheStrategy;
8
+ static readonly context: {
9
+ __context__: BrandVisualProviderContext;
10
+ };
11
+ }
12
+ export default BrandVisualProviderContext;
@@ -0,0 +1,7 @@
1
+ import { createContext } from '@lit/context';
2
+ import { TAG_NAME } from './brandvisualprovider.constants';
3
+ class BrandVisualProviderContext {
4
+ }
5
+ // create typed lit context as part of the BrandVisualProviderContext
6
+ BrandVisualProviderContext.context = createContext(TAG_NAME);
7
+ export default BrandVisualProviderContext;
@@ -0,0 +1,3 @@
1
+ type BrandVisualSet = 'momentum-brand-visuals' | 'custom-brand-visuals';
2
+ type CacheStrategy = 'in-memory-cache' | 'web-cache-api';
3
+ export type { BrandVisualSet, CacheStrategy };
@@ -0,0 +1,7 @@
1
+ import BrandVisualProvider from './brandvisualprovider.component';
2
+ export default BrandVisualProvider;
3
+ declare global {
4
+ interface HTMLElementTagNameMap {
5
+ ['mdc-brandvisualprovider']: BrandVisualProvider;
6
+ }
7
+ }
@@ -0,0 +1,4 @@
1
+ import BrandVisualProvider from './brandvisualprovider.component';
2
+ import { TAG_NAME } from './brandvisualprovider.constants';
3
+ BrandVisualProvider.register(TAG_NAME);
4
+ export default BrandVisualProvider;
@@ -11,9 +11,9 @@ import { html } from 'lit';
11
11
  import { property, state } from 'lit/decorators.js';
12
12
  import { Component } from '../../models';
13
13
  import providerUtils from '../../utils/provider';
14
+ import { assetFetch } from '../../utils/asset-fetch';
14
15
  import IconProvider from '../iconprovider/iconprovider.component';
15
16
  import styles from './icon.styles';
16
- import { svgFetch } from './icon.utils';
17
17
  import { DEFAULTS } from './icon.constants';
18
18
  /**
19
19
  * @tagname mdc-icon
@@ -80,13 +80,14 @@ class Icon extends Component {
80
80
  return this.abortController.signal;
81
81
  };
82
82
  // fetch icon data (including caching logic)
83
- return svgFetch({
83
+ return assetFetch({
84
84
  url,
85
85
  name: this.name,
86
86
  fileExtension,
87
87
  cacheName,
88
88
  cacheStrategy,
89
89
  renewSignal,
90
+ assetType: 'icon',
90
91
  })
91
92
  .then(iconData => {
92
93
  // parse the fetched icon string to an html element and set the attributes
@@ -11,10 +11,10 @@ import { html } from 'lit';
11
11
  import { property, state } from 'lit/decorators.js';
12
12
  import { Component } from '../../models';
13
13
  import providerUtils from '../../utils/provider';
14
+ import { assetFetch } from '../../utils/asset-fetch';
14
15
  import IllustrationProvider from '../illustrationprovider/illustrationprovider.component';
15
16
  import { ROLE } from '../../utils/roles';
16
17
  import styles from './illustration.styles';
17
- import { svgFetch } from './illustration.utils';
18
18
  import { DEFAULTS } from './illustration.constants';
19
19
  /**
20
20
  * @tagname mdc-illustration
@@ -82,13 +82,14 @@ class Illustration extends Component {
82
82
  return this.abortController.signal;
83
83
  };
84
84
  // fetch illustration data (including caching logic)
85
- return svgFetch({
85
+ return assetFetch({
86
86
  url,
87
87
  name: this.name,
88
88
  fileExtension,
89
89
  cacheName,
90
90
  cacheStrategy,
91
91
  renewSignal,
92
+ assetType: 'illustration',
92
93
  })
93
94
  .then(illustrationData => {
94
95
  // parse the fetched illustration string to an html element and set the attributes